# HG changeset patch # User Dave Smith # Date 1386717896 0 # Node ID 9de72de14ab3753c3e7b67b14da9e73ac51429c3 # Parent a628135958e7cc19d66bb1a4b86c75ea2cfc86c7 USASR-1307: customize CSS and override class template diff -r a628135958e7 -r 9de72de14ab3 src/main/groovy/org/ssdt_ohio/gradle/tasks/UserDoc.groovy --- a/src/main/groovy/org/ssdt_ohio/gradle/tasks/UserDoc.groovy Tue Dec 10 22:53:57 2013 +0000 +++ b/src/main/groovy/org/ssdt_ohio/gradle/tasks/UserDoc.groovy Tue Dec 10 23:24:56 2013 +0000 @@ -3,6 +3,7 @@ import org.codehaus.groovy.tools.groovydoc.ClasspathResourceManager import org.codehaus.groovy.tools.groovydoc.FileOutputTool import org.codehaus.groovy.tools.groovydoc.GroovyDocTool +import org.codehaus.groovy.tools.groovydoc.OutputTool import org.codehaus.groovy.tools.groovydoc.gstringTemplates.GroovyDocTemplateInfo import org.gradle.api.InvalidUserDataException import org.gradle.api.file.FileCollection @@ -149,7 +150,7 @@ * {@link GroovyDocTemplateInfo#DEFAULT_PACKAGE_TEMPLATES}. */ protected String[] getPackageTemplates() { - return GroovyDocTemplateInfo.DEFAULT_PACKAGE_TEMPLATES; + return UserDocTemplateInfo.DEFAULT_PACKAGE_TEMPLATES; } /** @@ -161,7 +162,7 @@ * {@link GroovyDocTemplateInfo#DEFAULT_DOC_TEMPLATES}. */ protected String[] getDocTemplates() { - return GroovyDocTemplateInfo.DEFAULT_DOC_TEMPLATES; + return UserDocTemplateInfo.DEFAULT_DOC_TEMPLATES; } /** @@ -173,6 +174,6 @@ * {@link GroovyDocTemplateInfo#DEFAULT_CLASS_TEMPLATES}. */ protected String[] getClassTemplates() { - return GroovyDocTemplateInfo.DEFAULT_CLASS_TEMPLATES; + return UserDocTemplateInfo.DEFAULT_CLASS_TEMPLATES; } } diff -r a628135958e7 -r 9de72de14ab3 src/main/groovy/org/ssdt_ohio/gradle/tasks/UserDocTemplateInfo.groovy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/groovy/org/ssdt_ohio/gradle/tasks/UserDocTemplateInfo.groovy Tue Dec 10 23:24:56 2013 +0000 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013. Ohio Department of Education. - All Rights Reserved. + * Unauthorized copying of this file, in any medium, is strictly prohibited. + * Written by State Software Development Team (http://ssdt.oecn.k12.oh.us/) + */ + +package org.ssdt_ohio.gradle.tasks + + +class UserDocTemplateInfo { + + private static final String USERDOC_BASEDIR = "org/ssdt_ohio/gradle/userdoc/templates/"; + + private static final String TEMPLATE_BASEDIR = "org/codehaus/groovy/tools/groovydoc/gstringTemplates/"; + private static final String DOCGEN_BASEDIR = "org/codehaus/groovy/tools/"; + public static final String[] DEFAULT_DOC_TEMPLATES = [ // top level templates + TEMPLATE_BASEDIR + "topLevel/index.html", + TEMPLATE_BASEDIR + "topLevel/overview-frame.html", // needs all package names + TEMPLATE_BASEDIR + "topLevel/allclasses-frame.html", // needs all packages / class names + TEMPLATE_BASEDIR + "topLevel/overview-summary.html", // needs all packages + TEMPLATE_BASEDIR + "topLevel/help-doc.html", + TEMPLATE_BASEDIR + "topLevel/index-all.html", + TEMPLATE_BASEDIR + "topLevel/deprecated-list.html", + USERDOC_BASEDIR + "stylesheet.css", // copy default one, may override later + TEMPLATE_BASEDIR + "topLevel/inherit.gif", + DOCGEN_BASEDIR + "groovy.ico", + ] + + public static final String[] DEFAULT_PACKAGE_TEMPLATES = [ // package level templates + TEMPLATE_BASEDIR + "packageLevel/package-frame.html", + TEMPLATE_BASEDIR + "packageLevel/package-summary.html" + ] + + public static final String[] DEFAULT_CLASS_TEMPLATES = [ // class level templates + USERDOC_BASEDIR + "classDocName.html" + ] + + +} diff -r a628135958e7 -r 9de72de14ab3 src/main/resources/org/ssdt_ohio/gradle/userdoc/templates/classDocName.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/resources/org/ssdt_ohio/gradle/userdoc/templates/classDocName.html Tue Dec 10 23:24:56 2013 +0000 @@ -0,0 +1,645 @@ + + + + + + +<% + def title = classDoc.name() + (props.docTitle ? " (${props.docTitle})" : "") + def isVisible = { it.isPublic() || (it.isProtected() && props.protectedScope == 'true') || (!it.isProtected() && !it.isPrivate() && props.packageScope == 'true') || props.privateScope == 'true' } + def isVisibleExt = { t -> java.lang.reflect.Modifier.isPublic(t.modifiers) || java.lang.reflect.Modifier.isProtected(t.modifiers) } + def visibleFields = classDoc.fields().findAll(isVisible) + def visibleProperties = classDoc.properties() // props visible be defn + def visibleMethods = classDoc.methods().findAll(isVisible) + def visibleConstructors = classDoc.constructors().findAll(isVisible) + def visibleNested = classDoc.innerClasses().findAll(isVisible) + boolean hasFields = !classDoc.isAnnotationType() && visibleFields + boolean hasProperties = !classDoc.isAnnotationType() && visibleProperties + boolean hasElements = classDoc.isAnnotationType() && visibleFields + boolean methodSummaryShown = visibleMethods + boolean fieldSummaryShown = hasFields + boolean hasEnumConstants = classDoc.enumConstants() + def dolink = { t, boolean b -> + boolean isArray = false + if (!t || t instanceof String) { + return classDoc.getDocUrl(t, b) + } + if (t instanceof org.codehaus.groovy.tools.groovydoc.ArrayClassDocWrapper) { + t = t.delegate + isArray = true + } + if (t instanceof org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDoc) { + if (t.fullPathName == 'def') return classDoc.getDocUrl("java.lang.Object def", b) + return "" + (b ? t.qualifiedTypeName() : t.name()) + "" + (isArray ? "[]" : "") + } + return classDoc.getDocUrl(t.qualifiedTypeName(), b) + (isArray ? "[]" : "") + } + def linkfull = { t -> dolink(t, true) } + def linkable = { t -> dolink(t, false) } + def modifiersWithIgnore = { t, boolean ignorePublic -> + (t.isPrivate()?"private ":"") + + (t.isPublic() && !ignorePublic?"public ":"") + + (t.isProtected()?"protected ":"") + + (t.isStatic()?"static ":"") + + (t.isFinal()?"final ":"") + + (t.respondsTo('isAbstract') && t.isAbstract()?"abstract ":"") + } + def modifiers = { t -> modifiersWithIgnore(t, classDoc.isGroovy()) } + def modifiersBrief = { t -> + (t.isPrivate()?"private ":"") + + (t.isProtected()?"protected ":"") + + (t.isStatic()?"static ":"") + } + def annotations = { t, sepChar -> + t.annotations() ? t.annotations().collect { + // it.isTypeAvailable() ? '@'+linkable(it.type().name())+(it.description()-('@'+it.type().name())): it.description() + it.description() + }.join(sepChar) + sepChar : '' + } + def elementTypes = [ + "required":"true", + "optional":"false" + ] + def isRequired = { f, v -> def req = f.constantValueExpression() == null; req.toString() == v } + def upcase = { n -> n[0].toUpperCase() + n[1..-1] } + def paramsOf = { n, boolean brief -> n.parameters().collect{ param -> (brief?'':annotations(param, ' ')) + linkable(param.isTypeAvailable()?param.type():param.typeName()) + (param.vararg()?'... ':' ') + param.name() + (param.defaultValue() ? " = " + param.defaultValue():"") }.join(", ") } + def nameFromParams = { n -> n.name() + '(' + n.parameters().collect{ param -> param.isTypeAvailable()?param.type().qualifiedTypeName():param.typeName() }.join(', ') + ')' } + def nameFromJavaParams = { n -> n.name + '(' + n.parameterTypes.collect{ param -> param.name }.join(', ') + ')' } +%> + + + +${title} + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+<% if (props.header) { %>${props.header}<% } %> +
+ + + +
+ +

+<% +def pkg = classDoc.containingPackage().nameWithDots() +if (pkg != "DefaultPackage") { +%> + +${pkg} +
+<% } %> + ${classDoc.typeDescription} ${classDoc.name()}

+<% +def parents = classDoc.isInterface() ? classDoc.parentInterfaces : classDoc.parentClasses +if (parents.size() >= 2) { + %>
<%
+    parents.eachWithIndex { p, i ->
+        %>${(i > 0 ? "  " * i + "  " * (i - 1) + "" : "") + ( i == parents.size() - 1 ? p.qualifiedTypeName() : linkfull(p))}\n<%
+    }
+    %>
<% +} +if (classDoc.isInterface()) { + Set interfaces = classDoc.parentInterfaces + interfaces -= classDoc + if (interfaces) { + %>
All Superinterfaces:
${interfaces.collect{ linkable(it) }.join(', ')}
<% + } +} else { + // TODO follow up the tree collecting interfaces seen? + def interfaces = classDoc.interfaces() + if (interfaces) { + %>
All Implemented Interfaces:
${interfaces.collect{ linkable(it) }.join(', ')}
<% + } +} +%>
+
${annotations(classDoc, '\n') + modifiers(classDoc) + classDoc.typeSourceDescription + ' ' + classDoc.name()}
+<% if (classDoc.isInterface() && classDoc.interfaces()) {
+%>extends ${classDoc.interfaces().collect{ linkable(it) }.join(', ')}
+<% } else if (classDoc.superclass()) {
+%>extends ${linkable(classDoc.superclass())}
+<% } %>
+
+<% if (classDoc.commentText()) { %> +

+${classDoc.commentText()} +

+
+<% } %> + + + + +<% if (visibleNested) { %> + + + + + <% for (c in visibleNested) { %> + + + + + <% } %> +
+ Nested Class Summary
+ ${modifiersBrief(c) + c.typeSourceDescription} + ${linkable(c)} +
+

${c.firstSentenceCommentText()}

+
+   +<% } %> + + + + +<% if (hasEnumConstants) { %> + + + + + <% for (ec in classDoc.enumConstants()) { %> + + + + <% } %> +
+ Enum Constant Summary
+ ${ec.name()} +
+

${ec.firstSentenceCommentText()}

+
+   +<% } %> + + + + +<% if (hasFields) { %> + + + + + <% for (field in visibleFields) { %> + + + + + <% } %> +
+ Field Summary
+ ${modifiersBrief(field) + linkable(field.type())} + ${field.name()} +
+

${field.firstSentenceCommentText()}

+
+   +<% } + classes = [] + if (classDoc.isInterface()) { + classes.addAll(classDoc.interfaces().toList()) + } else { + if (classDoc.superclass()) classes += classDoc.superclass() + else classes += new org.codehaus.groovy.tools.groovydoc.ExternalGroovyClassDoc(Object.class) + } + visited = [classDoc] as Set + while (classes) { + Set nextLevel = [] + classes.each { c -> + if (c.isInterface()) nextLevel.addAll(c.interfaces().toList()) + else if (c.superclass() && c.qualifiedTypeName() != 'java.lang.Object') nextLevel += c.superclass() + nextLevel -= visited + visited += nextLevel + def list = [] + if (c instanceof org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDoc) { + list = c.fields().findAll(isVisible).collect { field -> + "${field.name()}" + } + } else { + list = c.externalClass().fields.findAll{ isVisibleExt(it) }.collect { field -> + // "${field.name()}" + field.name + } + } + if (list) { + if (!fieldSummaryShown) { + fieldSummaryShown = true + %> + + + +
+ Field Summary
+  <% + } + %> + + +
+ Fields inherited from ${c.typeSourceDescription} ${linkable(c)} +
${list.join(', ')}
+  <% + } + } + classes = nextLevel + } +%> + + + + +<% if (hasProperties) { %> + + + + + <% for (prop in visibleProperties) { %> + + + + + <% } %> +
+ Property Summary
+ ${modifiersBrief(prop) + linkable(prop.type())} + ${prop.name()} +
+

${prop.firstSentenceCommentText()}

+
+   +<% } %> + + + +<% if (hasElements) { %> + <% elementTypes.each { k, v -> %> + + <% if (visibleFields.any{ isRequired(it, v) }) { %> + + + + + <% for (element in visibleFields) { %> + <% if (isRequired(element, v)) { %> + + + + + <% } %> + <% } %> +
+ ${upcase(k)} Element Summary
+ ${modifiersBrief(element) + element.type().typeName()} + ${element.name()} +
+

${element.firstSentenceCommentText()}

+
+ <% } %> +   + <% } %> +<% } %> + + + + +<% if (visibleConstructors) { %> + + + + + <% for (constructor in visibleConstructors) { %> + + + + <% } %> +
+ Constructor Summary
+ ${modifiersBrief(constructor)}${constructor.name()}(${paramsOf(constructor, true)}) +
+

${constructor.firstSentenceCommentText()}

+
+   +<% } %> + + + + +<% if (visibleMethods) { %> + + + + + <% for (method in visibleMethods) { %> + + + + + <% } %> +
+ Method Summary
+ ${modifiersBrief(method)}${linkable(method.returnType())} + + ${method.name()}(${paramsOf(method, true)}) +
+

${method.firstSentenceCommentText()}

+
+   +<% } + Set classes = [] + if (classDoc.isInterface()) { + classes.addAll(classDoc.interfaces().toList()) + } else { + if (classDoc.superclass()) classes += classDoc.superclass() + else classes += new org.codehaus.groovy.tools.groovydoc.ExternalGroovyClassDoc(Object.class) + } + Set visited = [classDoc] as Set + while (classes) { + Set nextLevel = [] + classes.each { c -> + if (c.isInterface()) nextLevel.addAll(c.interfaces().toList()) + else if (c.superclass() && c.qualifiedTypeName() != 'java.lang.Object') nextLevel += c.superclass() + nextLevel -= visited + visited += nextLevel + def list = [] + if (c instanceof org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDoc) { + list = c.methods().findAll(isVisible).collect { method -> + "${method.name()}" + } + } else { + list = c.externalClass().methods.findAll{ isVisibleExt(it) }.collect { method -> + linkable(c.externalClass().name + "#" + nameFromJavaParams(method) + " " + method.name) + } + } + if (list) { + if (!methodSummaryShown) { + methodSummaryShown = true + %> + + + +
+ Method Summary
+  <% + } + %> + + +
+ Methods inherited from ${c.typeSourceDescription} ${linkable(c)} +
${list.join(', ')}
+  <% + } + } + classes = nextLevel + } +%> + +

+ + + + +<% if (hasEnumConstants) { %> + + + + +
+ Enum Constant Detail
+ <% for (ec in classDoc.enumConstants()) { %> +

${ec.name()}

+
${modifiers(ec) + '' + classDoc.name() + ''} ${ec.name()}
+
+
${ec.commentText()} +
+

+

+
+ <% } %> +   +<% } %> + + + + +<% if (hasFields) { %> + + + + +
+ Field Detail
+ <% for (field in visibleFields) { %> +

${field.name()}

+
${annotations(field, '\n') + modifiersWithIgnore(field, false) + linkable(field.type())} ${field.name()}
+
+
${field.commentText()} +
+

+

+
+ <% } %> +   +<% } %> + + + + +<% if (hasProperties) { %> + + + + +
+ Property Detail
+ <% for (prop in visibleProperties) { %> +

${prop.name()}

+
${annotations(prop, '\n') + modifiers(prop) + linkable(prop.type())} ${prop.name()}
+
+
${prop.commentText()} +
+

+

+
+ <% } %> +   +<% } %> + + + + +<% if (hasElements) { %> + + + + +
+ Element Detail
+ <% for (element in visibleFields) { %> +

${element.name()}

+
${modifiers(element) + linkable(element.type())} ${element.name()}
+
+
${element.commentText()} +
+

+

+
+ <% } %> +   +<% } %> + + + + +<% if (visibleConstructors) { %> + + + + +
+ Constructor Detail
+ <% for (constructor in visibleConstructors) { %> +

+ ${constructor.name()}

+
${annotations(constructor, '\n') + modifiers(constructor)}${constructor.name()}(${paramsOf(constructor, false)})
+
+
${constructor.commentText()} +
+

+

+
+ <% } %> +   +<% } %> + + + + +<% if (visibleMethods) { %> + + + + +
+ Method Detail
+ <% for (method in visibleMethods) { %> +

+ ${method.name()}

+
${annotations(method, '\n') + modifiers(method)}${linkable(method.returnType())} ${method.name()}(${paramsOf(method, false)})
+
+
${method.commentText()} +
+

+

+
+ <% } %> +   +<% } %> + + +

${props['footer']?:""}

+
+ + + diff -r a628135958e7 -r 9de72de14ab3 src/main/resources/org/ssdt_ohio/gradle/userdoc/templates/stylesheet.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/resources/org/ssdt_ohio/gradle/userdoc/templates/stylesheet.css Tue Dec 10 23:24:56 2013 +0000 @@ -0,0 +1,215 @@ +.code, pre +{ + border: 1px dashed #6699CC; + background-color: #F4F4F4; + padding: 5px; +} + +body +{ + font-size: 10pt; + font-family: 'Lucida Grande',verdana,arial,helvetica,sans-serif; + background-color: #fff; + color: #333; +} + +/* Link colors */ +a +{ + color:#569D2F; + text-decoration:none; +} + +a:hover +{ + text-decoration:underline; +} + +/* Headings */ +h1 +{ + background: url(tapestry.png) no-repeat; + font-size:28px; + color:#007c00; + padding: 2.0em; +} +h1,h2,h3 { + color: #569D2F; +} + +wbr:after +{ + content: "\00200B"; /* IE fix */ +} + +/* Table colors */ + +table +{ + background: #fff; + border-collapse: collapse; +} + +td +{ + border: 1px dotted #ccc; + background: #F4F4F4; +} + +th +{ + border:none; + background-color: #569D2F; + color: white; + text-align: left; +} + +.TableHeadingColor th +{ + background-color: #569D2F; + background-repeat: repeat-x; + color:#fff; + font-size:14px; + height:26px; +} +.TableHeadingColor th font[size="+2"] +{ + font-size: 10pt; +} +table.parameters tbody th +{ + background: #F4F4F4; + color: #333; + border: 1px dotted #ccc; + font-weight: normal; +} +table.parameters thead tr.columnHeaders th +{ + background: #e6e6e6; + color: #6e6e6e; + border-left: 1px dotted #999; + border-right: 1px dotted #999; +} +body > dt > b +{ + display: block; + padding: 0.3em 0 0 0.3em; + margin-top: 1em; + background: #569D2F; + color: #fff; + border: 1px solid black; + font-size: 14px; + height: 26px; +} + +.TableSubHeadingColor +{ + background: #f7ffee; + +} +.TableSubHeadingColor a +{ + color: white; + text-decoration: underline; +} +.TableSubHeadingColor a:hover +{ + color: white; + text-decoration: underline; +} + +.TableRowColor +{ + background: #fff; +} + +.TableRowColor a +{ + border-bottom:none; + color:#569D2F; + font-weight:normal; +} + +tr.TableRowColor:hover +{ + background:#eef2e1; +} + + +/* Font used in left-hand frame lists */ +.FrameTitleFont +{ + font-size: 120%; + font-weight:bold; +} + +.FrameTitleFont a +{ + color: #333; +} + +.FrameHeadingFont +{ + font-weight: bold; + font-size:95%; +} + +.FrameItemFont +{ + line-height:130%; + font-size: 95%; +} + +.FrameItemFont a +{ + color:#333; +} + +.FrameItemFont a:hover +{ + color:#249901; + border-bottom:none; + text-decoration:underline; +} + +/* Navigation bar fonts and colors */ +.NavBarCell1 +{ + background-color:#fff; + border:none; +} + +.NavBarCell1Rev +{ + background-color:#e3faa5; + border:1px solid #9ad00c; + padding:0; + margin:0; +} + +.NavBarCell1 a +{ + color:#333; + text-decoration:none; +} + +.NavBarFont1Rev +{ + +} + +.NavBarCell2 +{ + border:none; +} + +.NavBarCell2 a +{ + color:#569D2F; + font-size:90%; +} + +.NavBarCell3 +{ + border:none; +}