mirror of https://github.com/sbt/sbt.git
Docs: auto-generate /index.html from <version>/docs/home.html and add version selection
This commit is contained in:
parent
840ddbffff
commit
28d3118d1d
|
|
@ -12,10 +12,16 @@
|
|||
object Docs
|
||||
{
|
||||
val cnameFile = SettingKey[File]("cname-file", "Location of the CNAME file for the website.")
|
||||
val SnapshotPath = "snapshot"
|
||||
val ReleasePath = "release"
|
||||
val DocsPath = "docs"
|
||||
val IndexHtml = "index.html"
|
||||
val HomeHtml = "home.html"
|
||||
val VersionPattern = """(\d+)\.(\d+)\.(\d+)(-.+)?""".r.pattern
|
||||
|
||||
def settings: Seq[Setting[_]] =
|
||||
site.settings ++
|
||||
site.sphinxSupport("docs") ++
|
||||
site.sphinxSupport(DocsPath) ++
|
||||
site.includeScaladoc("api") ++
|
||||
siteIncludeSxr("sxr") ++
|
||||
ghPagesSettings
|
||||
|
|
@ -41,10 +47,25 @@ object Docs
|
|||
IO.copy(mappings map { case (file, target) => (file, versioned / target) })
|
||||
IO.copyFile(cname, repo / cname.getName)
|
||||
IO.touch(repo / ".nojekyll")
|
||||
linkSite(repo, v, if(snap) "snapshot" else "release", s.log)
|
||||
IO.write(repo / "versions.js", versionsJs(sortVersions(collectVersions(repo))))
|
||||
if(!snap)
|
||||
RootIndex(versioned / DocsPath / "home.html", repo / IndexHtml)
|
||||
linkSite(repo, v, if(snap) SnapshotPath else ReleasePath, s.log)
|
||||
s.log.info("Copied site to " + versioned)
|
||||
repo
|
||||
}
|
||||
def versionsJs(vs: Seq[String]): String = "var availableDocumentationVersions = " + vs.mkString("['", "', '", "']")
|
||||
// names of all directories that are explicit versions
|
||||
def collectVersions(base: File): Seq[String] = (base * versionFilter).get.map(_.getName)
|
||||
def sortVersions(vs: Seq[String]): Seq[String] = vs.sortBy(versionComponents).reverse
|
||||
def versionComponents(v: String): Option[(Int,Int,Int,Option[String])] = {
|
||||
val m = VersionPattern.matcher(v)
|
||||
if(m.matches())
|
||||
Some( (m.group(1).toInt, m.group(2).toInt, m.group(3).toInt, Option(m.group(4))) )
|
||||
else
|
||||
None
|
||||
}
|
||||
def versionFilter = new PatternFilter(VersionPattern) && DirectoryFilter
|
||||
|
||||
def linkSite(base: File, to: String, from: String, log: Logger) {
|
||||
val current = base / to
|
||||
|
|
@ -60,4 +81,42 @@ object Docs
|
|||
case 0 => ()
|
||||
case code => error("Could not create symbolic link '" + file.getAbsolutePath + "' with path " + path)
|
||||
}
|
||||
}
|
||||
object RootIndex
|
||||
{
|
||||
import Docs._
|
||||
import org.jsoup._
|
||||
|
||||
def apply(versionIndex: File, to: File)
|
||||
{
|
||||
val doc = Jsoup.parse(versionIndex, "UTF-8")
|
||||
rewriteLinks(doc)
|
||||
removeSearch(doc)
|
||||
IO.write(to, doc.outerHtml)
|
||||
}
|
||||
def retargetIndexLink(original: String): String =
|
||||
if(isAbsolute(original) || original.startsWith("#"))
|
||||
original
|
||||
else
|
||||
ReleasePath + "/docs/" + original
|
||||
|
||||
def isAbsolute(s: String): Boolean = (new java.net.URI(s)).isAbsolute
|
||||
|
||||
def rewriteLinks(doc: nodes.Document)
|
||||
{
|
||||
rewriteLinks(doc, "*", "href")
|
||||
rewriteLinks(doc, "script", "src")
|
||||
}
|
||||
def rewriteLinks(doc: nodes.Document, elemName: String, attrName: String): Unit =
|
||||
for(elem <- select(doc, elemName + "[" + attrName + "]"))
|
||||
elem.attr(attrName, retargetIndexLink(elem.attr(attrName)))
|
||||
|
||||
def removeSearch(doc: nodes.Document): Unit =
|
||||
doc.select(".search").remove()
|
||||
|
||||
def select(doc: nodes.Document, s: String) =
|
||||
{
|
||||
import collection.JavaConverters._
|
||||
doc.select(s).iterator.asScala
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
libraryDependencies += "net.databinder" %% "dispatch-http" % "0.8.8"
|
||||
libraryDependencies ++= Seq(
|
||||
"net.databinder" %% "dispatch-http" % "0.8.8",
|
||||
"org.jsoup" % "jsoup" % "1.7.1"
|
||||
)
|
||||
|
||||
addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "0.6.0")
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
{% extends "basic/layout.html" %}
|
||||
|
||||
{% set script_files = script_files + ['../../versions.js'] %}
|
||||
{% set script_files = script_files + ['_static/set-versions.js'] %}
|
||||
|
||||
{% set css_files = css_files + ['_static/base.css'] %}
|
||||
{% set css_files = css_files + ['_static/docs.css'] %}
|
||||
|
|
@ -73,7 +75,7 @@
|
|||
{%- endif %}
|
||||
</li>
|
||||
<li>
|
||||
Version {{ release|e }}
|
||||
<select id="versions"><option selected value="{{release}}">Version {{ release|e }}</option></select>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -99,5 +101,3 @@
|
|||
</div>
|
||||
{% block footer %}{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -208,3 +208,15 @@ input#submit-search {
|
|||
input#search-input {
|
||||
margin: 0px;
|
||||
}
|
||||
.breadcrumb li select {
|
||||
width: auto;
|
||||
height: auto;
|
||||
background-color: rgba(242, 242, 235, 0.1);
|
||||
border: 1px solid rgba(204, 204, 204, 0.5);
|
||||
padding: 1px;
|
||||
margin: -2px 0px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.breadcrumb li select option {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
$(document).ready(function() {
|
||||
// array of versions provided by short js file in root so that
|
||||
// old documentation versions do not need to be
|
||||
var versions = availableDocumentationVersions;
|
||||
var releasePath = 'release/';
|
||||
var snapshotPath = 'snapshot/';
|
||||
var docsPath = "docs/";
|
||||
|
||||
// get the version drop-down
|
||||
var select = $("#versions");
|
||||
// the currently selected value is the current version
|
||||
var selected = select.val();
|
||||
// clear the options, which should only include the current version
|
||||
select.html('');
|
||||
|
||||
// populate the options with the latest list of versions
|
||||
for(var i = 0; i < versions.length; i++) {
|
||||
var v = versions[i];
|
||||
var sel = '';
|
||||
if (v == selected) sel = 'selected ';
|
||||
select.append('<option ' + sel + 'value="' + v + '">Version ' + v + '</option>');
|
||||
}
|
||||
|
||||
// check if primary exists, go there if it does, or go to fallback if it does not
|
||||
var gotoIfExists = function(primary, fallback) {
|
||||
$.ajax({
|
||||
type: 'HEAD',
|
||||
url: primary,
|
||||
success: function() { document.location.href = primary },
|
||||
error: function() { document.location.href = fallback },
|
||||
});
|
||||
};
|
||||
|
||||
// return a new URL String with its path transformed by function f: String => String
|
||||
var mapPath = function(urlString, f) {
|
||||
var u = document.createElement('a');
|
||||
u.href = urlString;
|
||||
u.pathname = f(u.pathname);
|
||||
return u.href;
|
||||
};
|
||||
|
||||
// when an option is selected, switch to that version of the current page,
|
||||
// but if it doesn't exist, go to the index for that version
|
||||
select.change(function() {
|
||||
var newV = $(this).val();
|
||||
var oldLoc = document.location.href;
|
||||
|
||||
var changeVersion = function(oldPathname) {
|
||||
var newPath = newV + '/';
|
||||
var changed = oldPathname.replace(selected + '/', newPath).replace(snapshotPath, newPath).replace(releasePath, newPath);
|
||||
// This occurs for unversioned files, specifically /index.html.
|
||||
// Redirect to the versioned path in this case (won't work when previewing on the local filesytem)
|
||||
if (changed == oldPathname) changed = newPath + docsPath + changed;
|
||||
return changed;
|
||||
};
|
||||
var home = function(pathname) { return 'index.html'; };
|
||||
|
||||
gotoIfExists( mapPath(oldLoc, changeVersion), mapPath(oldLoc, home));
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue