Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
215 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import sbt._ | ||
import sbt.Keys._ | ||
import scala.collection.JavaConverters._ | ||
import com.lightbend.paradox.sbt.ParadoxPlugin.autoImport.paradoxMarkdownToHtml | ||
import io.circe._ | ||
import io.circe.syntax._ | ||
import org.jsoup.Jsoup | ||
import org.jsoup.nodes.Element | ||
|
||
case class SearchIndex(docs: Seq[SearchIndex.Section]) | ||
|
||
object SearchIndex { | ||
implicit val encoder: ObjectEncoder[SearchIndex] = Encoder.forProduct1("docs")(_.docs) | ||
|
||
case class Section(location: String, title: String, text: String) | ||
object Section { | ||
implicit val encoder: ObjectEncoder[Section] = Encoder.forProduct3("location", "text", "title")( | ||
page => (page.location, page.text, page.title)) | ||
} | ||
|
||
val Headers = Set("h1", "h2", "h3", "h4", "h5", "h6") | ||
|
||
def generate(target: File, mappings: Seq[(File, String)]): File = { | ||
def readSections(mapping: (File, String)): Seq[Section] = { | ||
val (file, location) = mapping | ||
val doc = Jsoup.parse(file, "UTF-8") | ||
val docTitle = { | ||
val title = doc.select("head title").text() | ||
Option(title.lastIndexOf(" · ")) | ||
.filter(_ > 0) | ||
.map(title.substring(0, _)) | ||
.getOrElse(title) | ||
} | ||
|
||
def headerLocation(header: Element) = | ||
Option(header.select("a[name]").first()) match { | ||
case Some(anchor) => location + "#" + anchor.attr("name") | ||
case None => location | ||
} | ||
|
||
def processElement(section: Section, elements: List[Element]): Seq[Section] = | ||
elements match { | ||
case header :: tail if Headers(header.tagName) => | ||
val location = headerLocation(header) | ||
val next = Section(location, header.text, "") | ||
Vector(section) ++ processElement(next, tail) | ||
case element :: tail => | ||
val text = | ||
if (section.text.isEmpty) element.text | ||
else section.text + "\n" + element.text | ||
processElement(section.copy(text = text.trim), tail) | ||
case Nil => | ||
Vector(section) | ||
} | ||
|
||
val elements = | ||
doc.select("body .md-content__searchable").asScala.flatMap(_.children.asScala).toList | ||
|
||
processElement(Section(location, docTitle, ""), elements) | ||
} | ||
|
||
val sections = mappings.flatMap(readSections).toList | ||
val searchIndex = SearchIndex(sections) | ||
val json = searchIndex.asJson.noSpaces | ||
val out = target / "search_index.json" | ||
IO.write(out, json) | ||
out | ||
} | ||
|
||
def mapping(scope: Configuration) = Def.task { | ||
val index = generate( | ||
(target in scope).value / "paradox-material-theme", | ||
(paradoxMarkdownToHtml in scope).value | ||
) | ||
index -> "mkdocs/search_index.json" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Search index generation | ||
|
||
To enable @ref:[site search](getting-started.md#site-search) you must also | ||
generate a `search_index.json` file which contains the content of your site. | ||
The following sections describe how to configure sbt to extract text from the | ||
HTML files generated by Paradox. | ||
|
||
## Project dependencies | ||
|
||
Add the following lines to either `project/plugins.sbt` or `project/build.sbt` | ||
so the index generator can use [jsoup] to process the HTML content and [circe] | ||
to serialize the index to JSON. | ||
|
||
@@ snip [project/plugins.sbt]($root$/project/plugins.sbt) { #search-dependencies } | ||
|
||
[jsoup]: https://jsoup.org/ | ||
[circe]: http://circe.io/ | ||
|
||
## Add generator output to the site | ||
|
||
Depending on whether you are using Paradox in a stand-alone fashion or sbt-site's | ||
[Paradox generator], you need to add a line to your `build.sbt` to make the search | ||
index part of your site. | ||
|
||
Stand-alone Paradox | ||
: @@ snip [build.sbt]($root$/build.sbt) { #search-paradox } | ||
|
||
Paradox using sbt-site | ||
: @@ snip [build.sbt]($root$/build.sbt) { #search-sbt-site } | ||
|
||
[Paradox generator]: http://www.scala-sbt.org/sbt-site/generators/paradox.html | ||
|
||
## Generate the search index | ||
|
||
The following code does the bulk work of reading in each HTML file to extract | ||
the text for each header. You should place it in a file named | ||
`project/SearchIndex.scala`. | ||
|
||
@@ snip [project/SearchIndex.scala]($root$/project/SearchIndex.scala) |