Skip to content

Commit

Permalink
[scaladoc] Display of comments is improved.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gilles Dubochet committed Dec 9, 2009
1 parent 25d82e1 commit a17785f
Show file tree
Hide file tree
Showing 11 changed files with 310 additions and 101 deletions.
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/ast/DocComments.scala
Expand Up @@ -182,7 +182,7 @@ trait DocComments { self: SymbolTable =>
out append replacement
start = idx
case None =>
println("no replacement for "+vname) // !!!
//println("no replacement for "+vname) // !!!
}
} else {
idx += 1
Expand Down Expand Up @@ -289,7 +289,7 @@ trait DocComments { self: SymbolTable =>
if (idx < str.length && (str charAt idx) == ' ') idx += 1
defs(sym) += vble -> str.substring(idx)
}
if (defs(sym).nonEmpty) println("vars of "+sym+" = "+defs(sym)) // !!!
//if (defs(sym).nonEmpty) println("vars of "+sym+" = "+defs(sym)) // !!!
}
}

Expand Down
15 changes: 12 additions & 3 deletions src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
Expand Up @@ -14,7 +14,8 @@ import xml.{Unparsed, XML, NodeSeq}
import xml.dtd.{DocType, PublicID}
import scala.collection._
import scala.util.NameTransformer
import java.io.File
import java.nio.channels.Channels
import java.io.{FileOutputStream, File}

/** An html page that is part of a Scaladoc site.
* @author David Bernard
Expand Down Expand Up @@ -54,7 +55,15 @@ abstract class HtmlPage { thisPage =>
</head>
{ body }
</html>
XML.save(pageFile.getPath, html, site.encoding, xmlDecl = false, doctype = doctype)
val fos = new FileOutputStream(pageFile.getPath)
val w = Channels.newWriter(fos.getChannel, site.encoding)
try {
w.write("<?xml version='1.0' encoding='" + site.encoding + "'?>\n")
w.write( doctype.toString + "\n")
w.write(xml.Xhtml.toXhtml(html))
}
finally { w.close() ; fos.close() }
//XML.save(pageFile.getPath, html, site.encoding, xmlDecl = false, doctype = doctype)
}

def templateToPath(tpl: TemplateEntity): List[String] = {
Expand Down Expand Up @@ -121,7 +130,7 @@ abstract class HtmlPage { thisPage =>
case Title(in, 3) => <h3>{ inlineToHtml(in) }</h3>
case Title(in, _) => <h4>{ inlineToHtml(in) }</h4>
case Paragraph(in) => <p>{ inlineToHtml(in) }</p>
case Code(data) => <p><code>{ Unparsed(data) }</code></p>
case Code(data) => <pre>{ Unparsed(data) }</pre>
case UnorderedList(items) =>
<ul>{items map { i => <li>{ blockToHtml(i) }</li>}}</ul>
case OrderedList(items) =>
Expand Down
94 changes: 74 additions & 20 deletions src/compiler/scala/tools/nsc/doc/html/page/Template.scala
Expand Up @@ -58,10 +58,7 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage {
</div>

{ signature(tpl, true) }

{ if (tpl.comment.isEmpty) NodeSeq.Empty else
<div id="comment">{ commentToHtml(tpl.comment) }</div>
}
{ memberToCommentHtml(tpl, true) }

<div id="template">

Expand Down Expand Up @@ -103,31 +100,88 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage {
val attributes: List[comment.Body] = Nil
<li name={ mbr.definitionName }>
{ signature(mbr, false) }
{ memberToCommentHtml(mbr, false) }
</li>
}

def memberToCommentHtml(mbr: MemberEntity, isSelf: Boolean): NodeSeq = mbr match {
case dte: DocTemplateEntity if isSelf && mbr.comment.isDefined =>
<div id="comment" class="fullcomment">{ memberToFullCommentHtml(mbr, isSelf) }</div>
case dte: DocTemplateEntity if !isSelf && mbr.comment.isDefined =>
<p class="comment cmt">{ inlineToHtml(mbr.comment.get.short) }</p>
case _ if mbr.comment.isDefined =>
<p class="shortcomment cmt">{ inlineToHtml(mbr.comment.get.short) }</p>
<div class="fullcomment">{ memberToFullCommentHtml(mbr, isSelf) }</div>
case _ => NodeSeq.Empty
}

def memberToFullCommentHtml(mbr: MemberEntity, isSelf: Boolean): NodeSeq =
<xml:group>
{ if (mbr.comment.isEmpty) NodeSeq.Empty else
<div class="comment cmt">{ commentToHtml(mbr.comment) }</div>
}
{ val prs: List[ParameterEntity] = mbr match {
case cls: Class if cls.isCaseClass => cls.typeParams ::: (cls.primaryConstructor map (_.valueParams.flatten)).toList.flatten
case cls: Class if cls.isCaseClass =>
cls.typeParams ::: (cls.primaryConstructor map (_.valueParams.flatten)).toList.flatten
case trt: Trait => trt.typeParams
case dfe: Def => dfe.typeParams ::: dfe.valueParams.flatten
case ctr: Constructor => ctr.valueParams.flatten
case _ => Nil
}
def paramCommentToHtml(pr: ParameterEntity) =
if (pr.comment.isEmpty) NodeSeq.Empty else
<li class={ if (pr.isTypeParam) "tparam" else "param" } name={ pr.name }>{
commentToHtml(pr.comment.get)
}</li>
if (prs.isEmpty) NodeSeq.Empty else
<ol class="paramcmts">{ prs map (paramCommentToHtml(_)) }</ol>
def mbrCmt = mbr.comment.get
def paramCommentToHtml(prs: List[ParameterEntity]): NodeSeq = prs match {
case Nil =>
NodeSeq.Empty
case (tp: TypeParam) :: rest =>
val paramEntry: NodeSeq = {
<dt class="tparam">{ tp.name }</dt><dd class="cmt">{ bodyToHtml(mbrCmt.typeParams(tp.name)) }</dd>
}
paramEntry ++ paramCommentToHtml(rest)
case (vp: ValueParam) :: rest =>
val paramEntry: NodeSeq = {
<dt class="param">{ vp.name }</dt><dd class="cmt">{ bodyToHtml(mbrCmt.valueParams(vp.name)) }</dd>
}
paramEntry ++ paramCommentToHtml(rest)
}
if (mbr.comment.isEmpty) NodeSeq.Empty else {
val cmtedPrs = prs filter {
case tp: TypeParam => mbrCmt.typeParams isDefinedAt tp.name
case vp: ValueParam => mbrCmt.valueParams isDefinedAt vp.name
}
if (cmtedPrs.isEmpty) NodeSeq.Empty else
<dl class="paramcmts block">{
paramCommentToHtml(cmtedPrs) ++ (
mbrCmt.result match {
case None => NodeSeq.Empty
case Some(cmt) =>
<dt>returns</dt><dd class="cmt">{ bodyToHtml(cmt) }</dd>
})
}</dl>
}
}
{ val fvs: List[comment.Paragraph] = mbr.visibility.toList ::: mbr.flags
if (fvs.isEmpty) NodeSeq.Empty else
<ol class="attributes">{ fvs map { fv => <li>{ inlineToHtml(fv.text) }</li> } }</ol>

<div class="block">{ fvs map { fv => { inlineToHtml(fv.text) ++ xml.Text(" ") } } }</div>
}
{ if (mbr.comment.isEmpty) NodeSeq.Empty else
<div class="comment">{ commentToHtml(mbr.comment) }</div>
{ def inheritanceElem(tpl: TemplateEntity): NodeSeq = tpl match {
case (dTpl: DocTemplateEntity) =>
<a href={ relativeLinkTo(dTpl) }>{ dTpl.name }</a>
case (ndTpl: NoDocTemplate) =>
xml.Text(ndTpl.name)
}
def inheritanceChain(tplss: List[TemplateEntity]): NodeSeq = (tplss: @unchecked) match {
case tpl :: Nil => inheritanceElem(tpl)
case tpl :: tpls =>
inheritanceElem(tpl) ++ xml.Text("") ++ inheritanceChain(tpls)
}
val inDefTpls = mbr.inDefinitionTemplates
if (inDefTpls.tail.isEmpty && (inDefTpls.head == mbr.inTemplate)) NodeSeq.Empty else {
<div class="block">
definition classes: { inheritanceChain(inDefTpls) }
</div>
}
}
</li>
}
</xml:group>

def kindToString(mbr: MemberEntity): String = mbr match {
case tpl: DocTemplateEntity =>
Expand Down Expand Up @@ -207,9 +261,9 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage {
</xml:group>
mbr match {
case dte: DocTemplateEntity if !isSelf =>
<a class="signature" href={ relativeLinkTo(dte) }>{ inside(hasLinks = false) }</a>
<h4 class="signature"><a href={ relativeLinkTo(dte) }>{ inside(hasLinks = false) }</a></h4>
case _ =>
<div class="signature">{ inside(hasLinks = true) }</div>
<h4 class="signature">{ inside(hasLinks = true) }</h4>
}
}

Expand Down
18 changes: 16 additions & 2 deletions src/compiler/scala/tools/nsc/doc/html/resource/lib/index.js
@@ -1,3 +1,6 @@
// © 2009 EPFL/LAMP
// written by Gilles Dubochet with contributions by Johannes Rudolph and "spiros"

$(document).ready(function(){
cleanPackage($("#tpl"));
$("#tpl ol > li span:contains('(class)')").replaceWith("<img class='icon' src='lib/class.png'/>");
Expand All @@ -11,7 +14,7 @@ $(document).ready(function(){
$("#quickflt").focus(function(event) {
$("#quickflt").select();
});
$("#quickflt").bind("keyup", function(event) {
function search() {
var query = $("#quickflt").attr("value");
// Regexp that matches CamelCase subbits: "BiSe" is
// "[a-z]*Bi[a-z]*Se" and matches "BitSet", "ABitSet", ...
Expand All @@ -28,7 +31,18 @@ $(document).ready(function(){
};
});
cleanPackage($("#tpl"));
});
pendingTimeout = undefined;
};
var pendingTimeout = undefined;
$("#quickflt").bind("keyup", function(event) {
if (event.keyCode == 27) { // escape
$("#quickflt").attr("value", "");
}
if (pendingTimeout != undefined) {
clearTimeout(pendingTimeout);
}
pendingTimeout = setTimeout(search, 200); //delay 0.2 sec
});
$("#tpl .packages > li").prepend("<a class='packhide'>hide</a>");
$("#tpl .packages > li > a.packhide").click(function(event){
var action = $(this).text();
Expand Down
103 changes: 80 additions & 23 deletions src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
Expand Up @@ -3,6 +3,7 @@
text-decoration: none;
font-family: inherit;
font-size: inherit;
font-weight: normal;
border-width: 0px;
padding: 0px;
margin: 0px;
Expand Down Expand Up @@ -87,6 +88,18 @@ a:hover {
background-color: #000000;
}

/* Member cells */

div.members > ol {
background-color: white;
}

div.members > ol > li {
display: block;
}

/* Member signatures */

.signature {
padding: 1px;
font-family: monospace;
Expand Down Expand Up @@ -120,52 +133,96 @@ a:hover {
color: #561414;
}

#template > div.members > ol {
background-color: white;
/* Comments text formating */

.cmt {}

.cmt p {
margin: 2px 0 2px 0;
}

.members > ol > li {
.cmt code {
font-family: monospace;
font-size: small;
}

.cmt pre {
display: block;
font-family: monospace;
font-size: small;
margin: 2px 0 2px 0;
}

/* Comments structured layout */

p.comment {
display: block;
margin-left: 80px;
}

.members .paramcmts {
p.shortcomment {
display: block;
margin-left: 80px;
cursor: help;
}

.members .paramcmts > li.tparam {
background-color: #ffcc66;
display: none;
div.fullcomment {
display: block;
margin: 10px 0 10px 0;
}

.members .paramcmts > li.param {
background-color: #cc99ff;
display: none;
#template div.fullcomment {
margin: 6px 0 6px 80px;
}

.members .attributes {
border-bottom-color: black;
border-bottom-style: solid;
border-bottom-width: 1px;
margin-left: 80px;
div.fullcomment .block {
padding: 2px 0 2px 0;
border-top: 1px solid black;
border-bottom: 1px solid black;
}

.members .attributes > li {
padding: 2px;
font-size: 10pt;
div.fullcomment .block + .block {
border-top: none;
}

div.fullcomment .block > h5 {
font-style: italic;
font-weight: normal;
display: inline-block;
}

.members .comment {
div.fullcomment .comment {
margin: 6px 0 6px 0;
}

div.fullcomment dl.paramcmts > dt {
display: block;
margin-left: 80px;
float: left;
font-weight: bold;
margin: 2px 4px 2px 0;
}

.comment > p {
margin-bottom: 4px;
margin-top: 4px;
div.fullcomment dl.paramcmts > dd {
display: block;
padding-left: 80px;
border-top: 1px dashed black;
border-bottom: 1px dashed black;
}

div.fullcomment dl.paramcmts > dt:first-child + dd {
border-top: none;
}

div.fullcomment dl.paramcmts > dd:last-child {
border-bottom: none;
}

div.fullcomment dl.paramcmts > dd + dt + dd {
border-top: none;
}

/* Members filter tool */

#mbrsel {
padding: 4px;
background-color: #cccccc;
Expand Down

0 comments on commit a17785f

Please sign in to comment.