summaryrefslogtreecommitdiff
path: root/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-03-06 07:39:19 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-03-09 11:59:07 -0800
commitc6ca941ccc017a8869f4def717cfeb640f965077 (patch)
treee21038cc55d3a4231544d148913504a754eafdf8 /src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala
parent9094822181c398b945b7f30ac1e2b05da9796f53 (diff)
downloadscala-c6ca941ccc017a8869f4def717cfeb640f965077.tar.gz
scala-c6ca941ccc017a8869f4def717cfeb640f965077.tar.bz2
scala-c6ca941ccc017a8869f4def717cfeb640f965077.zip
Moved scaladoc sources into separate directory.
This change is not externally visible. It moves the scaladoc sources into src/scaladoc and adds an ant target for building them. The compilation products are still packaged into scala-compiler.jar as before, but with a small change to build.xml a separate jar can be created instead.
Diffstat (limited to 'src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala')
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala224
1 files changed, 224 insertions, 0 deletions
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala
new file mode 100644
index 0000000000..229e26d699
--- /dev/null
+++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala
@@ -0,0 +1,224 @@
+/* NSC -- new Scala compiler
+ * Copyright 2007-2013 LAMP/EPFL
+ * @author David Bernard, Manohar Jonnalagedda
+ */
+
+package scala.tools.nsc
+package doc
+package html
+
+import base._
+import base.comment._
+import model._
+
+import scala.xml.NodeSeq
+import scala.xml.dtd.{DocType, PublicID}
+import scala.collection._
+import java.io.Writer
+
+/** An html page that is part of a Scaladoc site.
+ * @author David Bernard
+ * @author Gilles Dubochet */
+abstract class HtmlPage extends Page { thisPage =>
+ /** The title of this page. */
+ protected def title: String
+
+ /** The page description */
+ protected def description: String =
+ // unless overwritten, will display the title in a spaced format, keeping - and .
+ title.replaceAll("[^a-zA-Z0-9\\.\\-]+", " ").replaceAll("\\-+", " - ").replaceAll(" +", " ")
+
+ /** The page keywords */
+ protected def keywords: String =
+ // unless overwritten, same as description, minus the " - "
+ description.replaceAll(" - ", " ")
+
+ /** Additional header elements (links, scripts, meta tags, etc.) required for this page. */
+ protected def headers: NodeSeq
+
+ /** The body of this page. */
+ def body: NodeSeq
+
+ def writeFor(site: HtmlFactory) {
+ val doctype =
+ DocType("html", PublicID("-//W3C//DTD XHTML 1.1//EN", "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"), Nil)
+ val html =
+ <html>
+ <head>
+ <title>{ title }</title>
+ <meta name="description" content={ description }/>
+ <meta name="keywords" content={ keywords }/>
+ <meta http-equiv="content-type" content={ "text/html; charset=" + site.encoding }/>
+ { headers }
+ </head>
+ { body }
+ </html>
+
+ writeFile(site) { (w: Writer) =>
+ w.write("<?xml version='1.0' encoding='" + site.encoding + "'?>\n")
+ w.write(doctype.toString + "\n")
+ w.write(xml.Xhtml.toXhtml(html))
+ }
+
+ if (site.universe.settings.docRawOutput.value)
+ writeFile(site, ".raw") {
+ // we're only interested in the body, as this will go into the diff
+ _.write(body.text)
+ }
+
+ //XML.save(pageFile.getPath, html, site.encoding, xmlDecl = false, doctype = doctype)
+ }
+
+ /** Transforms an optional comment into an styled HTML tree representing its body if it is defined, or into an empty
+ * node sequence if it is not. */
+ def commentToHtml(comment: Option[Comment]): NodeSeq =
+ (comment map (commentToHtml(_))) getOrElse NodeSeq.Empty
+
+ /** Transforms a comment into an styled HTML tree representing its body. */
+ def commentToHtml(comment: Comment): NodeSeq =
+ bodyToHtml(comment.body)
+
+ def bodyToHtml(body: Body): NodeSeq =
+ body.blocks flatMap (blockToHtml(_))
+
+ def blockToHtml(block: Block): NodeSeq = block match {
+ case Title(in, 1) => <h3>{ inlineToHtml(in) }</h3>
+ case Title(in, 2) => <h4>{ inlineToHtml(in) }</h4>
+ case Title(in, 3) => <h5>{ inlineToHtml(in) }</h5>
+ case Title(in, _) => <h6>{ inlineToHtml(in) }</h6>
+ case Paragraph(in) => <p>{ inlineToHtml(in) }</p>
+ case Code(data) =>
+ <pre>{ SyntaxHigh(data) }</pre> //<pre>{ scala.xml.Text(data) }</pre>
+ case UnorderedList(items) =>
+ <ul>{ listItemsToHtml(items) }</ul>
+ case OrderedList(items, listStyle) =>
+ <ol class={ listStyle }>{ listItemsToHtml(items) }</ol>
+ case DefinitionList(items) =>
+ <dl>{items map { case (t, d) => <dt>{ inlineToHtml(t) }</dt><dd>{ blockToHtml(d) }</dd> } }</dl>
+ case HorizontalRule() =>
+ <hr/>
+ }
+
+ def listItemsToHtml(items: Seq[Block]) =
+ items.foldLeft(xml.NodeSeq.Empty){ (xmlList, item) =>
+ item match {
+ case OrderedList(_, _) | UnorderedList(_) => // html requires sub ULs to be put into the last LI
+ xmlList.init ++ <li>{ xmlList.last.child ++ blockToHtml(item) }</li>
+ case Paragraph(inline) =>
+ xmlList :+ <li>{ inlineToHtml(inline) }</li> // LIs are blocks, no need to use Ps
+ case block =>
+ xmlList :+ <li>{ blockToHtml(block) }</li>
+ }
+ }
+
+ def inlineToHtml(inl: Inline): NodeSeq = inl match {
+ case Chain(items) => items flatMap (inlineToHtml(_))
+ case Italic(in) => <i>{ inlineToHtml(in) }</i>
+ case Bold(in) => <b>{ inlineToHtml(in) }</b>
+ case Underline(in) => <u>{ inlineToHtml(in) }</u>
+ case Superscript(in) => <sup>{ inlineToHtml(in) }</sup>
+ case Subscript(in) => <sub>{ inlineToHtml(in) }</sub>
+ case Link(raw, title) => <a href={ raw } target="_blank">{ inlineToHtml(title) }</a>
+ case Monospace(in) => <code>{ inlineToHtml(in) }</code>
+ case Text(text) => scala.xml.Text(text)
+ case Summary(in) => inlineToHtml(in)
+ case HtmlTag(tag) => scala.xml.Unparsed(tag)
+ case EntityLink(target, link) => linkToHtml(target, link, hasLinks = true)
+ }
+
+ def linkToHtml(text: Inline, link: LinkTo, hasLinks: Boolean) = link match {
+ case LinkToTpl(dtpl: TemplateEntity) =>
+ if (hasLinks)
+ <a href={ relativeLinkTo(dtpl) } class="extype" name={ dtpl.qualifiedName }>{ inlineToHtml(text) }</a>
+ else
+ <span class="extype" name={ dtpl.qualifiedName }>{ inlineToHtml(text) }</span>
+ case LinkToMember(mbr: MemberEntity, inTpl: TemplateEntity) =>
+ if (hasLinks)
+ <a href={ relativeLinkTo(inTpl) + "#" + mbr.signature } class="extmbr" name={ mbr.qualifiedName }>{ inlineToHtml(text) }</a>
+ else
+ <span class="extmbr" name={ mbr.qualifiedName }>{ inlineToHtml(text) }</span>
+ case Tooltip(tooltip) =>
+ <span class="extype" name={ tooltip }>{ inlineToHtml(text) }</span>
+ case LinkToExternal(name, url) =>
+ <a href={ url } class="extype" target="_top">{ inlineToHtml(text) }</a>
+ case _ =>
+ inlineToHtml(text)
+ }
+
+ def typeToHtml(tpes: List[model.TypeEntity], hasLinks: Boolean): NodeSeq = tpes match {
+ case Nil =>
+ NodeSeq.Empty
+ case List(tpe) =>
+ typeToHtml(tpe, hasLinks)
+ case tpe :: rest =>
+ typeToHtml(tpe, hasLinks) ++ scala.xml.Text(" with ") ++ typeToHtml(rest, hasLinks)
+ }
+
+ 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)
+ scala.xml.Text(string.slice(inPos, string.length))
+ else if (inPos == starts.head)
+ toLinksIn(inPos, starts)
+ else {
+ scala.xml.Text(string.slice(inPos, starts.head)) ++ toLinksIn(starts.head, starts)
+ }
+ }
+ def toLinksIn(inPos: Int, starts: List[Int]): NodeSeq = {
+ val (link, width) = tpe.refEntity(inPos)
+ val text = comment.Text(string.slice(inPos, inPos + width))
+ linkToHtml(text, link, hasLinks) ++ toLinksOut(inPos + width, starts.tail)
+ }
+ if (hasLinks)
+ toLinksOut(0, tpe.refEntity.keySet.toList)
+ else
+ scala.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)
+ }
+
+ def hasPage(e: DocTemplateEntity) = {
+ e.isPackage || e.isTrait || e.isClass || e.isObject || e.isCaseClass
+ }
+
+ /** Returns the HTML code that represents the template in `tpl` as a hyperlinked name. */
+ def templateToHtml(tpl: TemplateEntity, name: String = null) = tpl match {
+ case dTpl: DocTemplateEntity =>
+ if (hasPage(dTpl)) {
+ <a href={ relativeLinkTo(dTpl) } class="extype" name={ dTpl.qualifiedName }>{ if (name eq null) dTpl.name else name }</a>
+ } else {
+ scala.xml.Text(if (name eq null) dTpl.name else name)
+ }
+ case ndTpl: NoDocTemplate =>
+ scala.xml.Text(if (name eq null) ndTpl.name else 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)
+ }
+
+ /** Returns the _big image name corresponding to the DocTemplate Entity (upper left icon) */
+ def docEntityKindToBigImage(ety: DocTemplateEntity) =
+ if (ety.isTrait && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None) "trait_to_object_big.png"
+ else if (ety.isTrait) "trait_big.png"
+ else if (ety.isClass && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None) "class_to_object_big.png"
+ else if (ety.isClass) "class_big.png"
+ else if ((ety.isAbstractType || ety.isAliasType) && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None) "type_to_object_big.png"
+ else if ((ety.isAbstractType || ety.isAliasType)) "type_big.png"
+ else if (ety.isObject && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None && ety.companion.get.isClass) "object_to_class_big.png"
+ else if (ety.isObject && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None && ety.companion.get.isTrait) "object_to_trait_big.png"
+ else if (ety.isObject && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None && (ety.companion.get.isAbstractType || ety.companion.get.isAliasType)) "object_to_trait_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
+}