All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.specs2.html.Indexing.scala Maven / Gradle / Ivy
package org.specs2
package html
import io.{DirectoryPath, FilePath, FileSystem}
import specification.core._
import org.specs2.fp._
import org.specs2.fp.syntax._
import control._
import org.specs2.concurrent.ExecutionEnv
import origami._
/**
* Fold functions to create index files
*/
object Indexing {
implicit def executionEnv: ExecutionEnv =
ExecutionEnv.fromGlobalExecutionContext
/**
* An Index fold creates an Index page based on all pages to index and
* saves it to a given file path
*/
def indexFold(path: FilePath): Fold[Operation, IndexedPage, Index] =
origami.fold.fromMonoidMap[Operation, IndexedPage, Index](Index.createIndex).mapFlatten((index: Index) =>
FileSystem.writeFile(path, Index.toJson(index)).as(index))
def createIndexedPages(env: Env, specifications: List[SpecStructure], outDir: DirectoryPath): List[IndexedPage] =
specifications.map(createIndexedPage(env, outDir))
def createIndexedPage(env: Env, outDir: DirectoryPath) = (spec: SpecStructure) => {
IndexedPage(
path = SpecHtmlPage.outputPath(outDir, spec).relativeTo(outDir),
title = spec.header.showWords,
contents = spec.textsList.foldLeft(new StringBuilder)((res, cur) => res.append(cur.description.show)).toString,
tags = spec.tagsList.flatMap(_.names).map(sanitize).toIndexedSeq)
}
def createEntries(page: IndexedPage): Vector[IndexEntry] =
Vector(IndexEntry(page.title, page.contents, page.tags, page.path))
/** remove quotes from names in order to add as json values */
def sanitize(name: String): String =
name.replace("\"", "\\\"")
}
case class IndexedPage(path: FilePath, title: String, contents: String, tags: IndexedSeq[String])
case class Index(entries: Vector[IndexEntry]) {
def add(entry: IndexEntry) = copy(entries :+ entry)
def add(other: Seq[IndexEntry]) = copy(entries ++ other)
}
object Index {
val empty = Index(Vector())
def toJson(index: Index): String = {
s"""
|var tipuesearch = {"pages": ${pages(index).mkString("[", ",\n", "]")}};
""".stripMargin
}
def pages(index: Index): Seq[String] =
index.entries.map(page)
def page(entry: IndexEntry): String =
s"""{"title":"${entry.title}", "text":"${sanitizeEntry(entry)}", "tags":${entry.tags.mkString("\""," ", "\"")}, "loc":"${entry.path.path}"}"""
/**
* the text that is used for indexing must be sanitized:
* - no newlines
* - ^ (because tipue search doesn't like it)
* - no markdown characters
*/
def sanitizeEntry(entry: IndexEntry): String =
entry.text.replace("\"", "\\\"")
.replace("\n", "")
.replace("^", "")
.replace("#####", "")
.replace("####", "")
.replace("###", "")
.replace("##", "")
.replace(" * ", "")
.replace("```", "")
.replace("", "")
.replace(" ", "")
implicit def IndexMonoid: Monoid[Index] = new Monoid[Index] {
def zero = Index(Vector())
def append(a: Index, b: =>Index) = Index(a.entries ++ b.entries)
}
val createIndex = (page: IndexedPage) => Index(Indexing.createEntries(page))
}
case class IndexEntry(title: String, text: String, tags: IndexedSeq[String], path: FilePath)