Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
Checking mergeability… Don’t worry, you can still create the pull request.
  • 11 commits
  • 4 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jun 21, 2014
@Shadowfiend Shadowfiend Add dexy target/script for building API docs.
Right now this doesn’t work because json-scalaz.
c23fc76
@Shadowfiend Shadowfiend Make build-api-docs script work standalone.
Running docs/scripts/build-api-docs.sh should now properly
send the resulting API documentation to target/docs/api.
aa110cb
@Shadowfiend Shadowfiend Handle API docs for multiple scala versions.
Before, the copying part of the build-api-docs task was failing
because built API docs go to target/scala-<version>/api, not
just target/api. We now properly copy all versions into the
working directory.
013a3f8
@Shadowfiend Shadowfiend Fix bulleted lists in CSS selectors documentation. f44895f
Commits on Jun 22, 2014
@Shadowfiend Shadowfiend Drop some dexy shell timeouts. c692607
@Shadowfiend Shadowfiend Retarget API docs off of the base docs dir.
The build-api-docs script now puts the API docs in the
api/scala-<version> under the docs/ directory in the dexy
working directory.
232a3a5
@Shadowfiend Shadowfiend Properly copy API docs to output directory.
This should also let us do further processing on the API docs.
a688e2f
Commits on Jun 23, 2014
@Shadowfiend Shadowfiend First pass at adding (better) search to API docs.
Right now we mostly just have the API docs builder script
run through a documentation helper that adds a JS file to
HTML files.

For now, we’re only doing the HTML files at the root of the
documentation directory, which isn’t terribly useful, but it does
work. More to come.
f26d4d2
Commits on Jun 24, 2014
@Shadowfiend Shadowfiend Recursively add search to API docs.
The “search” that’s being added is still wrong, but the
recursion is alllll riiiiiight.
45b8f55
@Shadowfiend Shadowfiend Adjust path to search.js based on file depth.
We do this by tracking a nestLevel during our recursive
descent and including it in the information describing each file.
We also wrap all that info in a FileInfo case class, which
replaces the old tuple.
056ac5b
@Shadowfiend Shadowfiend Extract basic API info from docs.
Not extracting the members yet, just the item type, its name,
and its signature.
d28f119
View
197 core/documentation-helpers/src/main/scala/net/liftweb/documentation/AddSearchToApiDocs.scala
@@ -0,0 +1,197 @@
+package net.liftweb
+package documentation
+
+import java.io.{File,FileWriter}
+
+import scala.io.Source
+import scala.xml._
+
+import common._
+import util.Html5
+import util.Helpers._
+
+sealed trait ItemType
+object ItemType {
+ case object Singleton extends ItemType
+ case object Class extends ItemType
+ case object Trait extends ItemType
+}
+
+case class FileInfo(file: File, contents: String, nestLevel: Int)
+
+case class MemberApiInfo(modifier: String, name: String, paramString: String, result: String)
+case class ApiInfo(itemType: ItemType, name: String, signature: String, members: List[MemberApiInfo])
+
+object AddSearchToApiDocs extends App {
+ object FileWithContents {
+ def unapply(file: File): Option[(File, String)] = {
+ tryo(Source.fromFile(file).mkString).map((file, _))
+ }
+ }
+
+ def apiFilesForDirectory(directoryFile: File, nestLevel: Int): Stream[FileInfo] = {
+ directoryFile.listFiles.toStream flatMap {
+ case file if file.getName.endsWith(".html") =>
+ tryo(Source.fromFile(file).mkString).map(FileInfo(file, _, nestLevel)).toStream
+ case directoryFile if directoryFile.isDirectory =>
+ apiFilesForDirectory(directoryFile, nestLevel + 1)
+ case _ =>
+ Stream.empty
+ }
+ }
+
+ def apiFiles: Box[Stream[FileInfo]] = {
+ val baseFile = new File(args(0))
+
+ for {
+ apiDirectory <-
+ ((Full(baseFile)
+ .filter(_.exists) ?~ s"'$baseFile' should be a directory, but does not exist.")
+ .filter(_.isDirectory) ?~ s"'$baseFile' should be a directory, not a file.")
+ } yield {
+ apiFilesForDirectory(apiDirectory, 0)
+ }
+ }
+
+ private def forElement(label: String, handlerFn: (Elem)=>Unit): (NodeSeq)=>NodeSeq = {
+ { ns: NodeSeq =>
+ ns match {
+ case matched: Elem if matched.label == label =>
+ handlerFn(matched)
+
+ matched
+
+ case other =>
+ other
+ }
+ }
+ }
+
+ private def hasClass_?(element: Elem, className: String) = {
+ element.attribute("class") match {
+ case Some(thing) =>
+ charSplit(thing.text, ' ').exists(_ == className)
+ case _ =>
+ false
+ }
+ }
+
+ /**
+ * Returns a transformation function that leaves its contents untouched, but
+ * extracts an ApiInfo from them. This ApiInfo is passed to the
+ * `assignmentFn` immediately before returning the unchanged contents.
+ */
+ def extractApiInfo(assignmentFn: (ApiInfo)=>Unit): (NodeSeq)=>NodeSeq = {
+ var info = ApiInfo(ItemType.Class, "", "", Nil)
+ var extracted = false
+
+ val extractType =
+ "body [class]" #> forElement("body", { body =>
+ if (hasClass_?(body, "value")) {
+ info.copy(itemType = ItemType.Singleton)
+ }
+
+ extracted = hasClass_?(body, "value") || hasClass_?(body, "type")
+ })
+
+ val extractName =
+ "#definition h1" #> forElement("h1", { h1 =>
+ info = info.copy(name = h1.text.trim.replaceAll("\\s+", " "))
+ })
+
+ val extractSignature =
+ "#signature" #> forElement("h4", { h4 =>
+ val itemType =
+ if (h4.text.contains("trait")) {
+ ItemType.Trait
+ } else {
+ info.itemType
+ }
+
+ info = info.copy(
+ itemType = itemType,
+ signature = h4.text.trim.replaceAll("\\s+", " ")
+ )
+ })
+
+ //val extractMembers =
+ // "#allMembers li" #> {
+ // }
+
+ val extractAll =
+ extractType andThen
+ extractName &
+ extractSignature
+
+ { ns: NodeSeq =>
+ extractAll(ns)
+
+ if (extracted)
+ assignmentFn(info)
+
+ ns
+ }
+ }
+
+ if (args.length < 1) {
+ Console.err.println(
+ "Expected one argument: the base directory of the API documentation to add search to."
+ )
+ } else {
+ val files =
+ apiFiles match {
+ case Failure(message, _, _) =>
+ Console.err.println(s"Something went wrong: $message")
+ sys.exit(1)
+ case Empty =>
+ Console.err.println(s"Something weird went wrong...")
+ sys.exit(1)
+
+ case Full(files) =>
+ files
+ }
+ apiFiles openOr {
+ Console.err
+ sys.exit(1)
+ Stream.empty
+ }
+
+ var apiInfo = List[ApiInfo]()
+
+ val conversionResults: Box[List[Unit]] =
+ files.map {
+ case FileInfo(file, fileContents, nestLevel) =>
+ println(s"Processing ${file.getName}")
+ Html5.parse(fileContents).map { docHtml =>
+ val directoryAdjustment = (1 to nestLevel).map(_ => "..").mkString("/")
+ val libPath = s"$directoryAdjustment/lib/search.js"
+
+ val transforms =
+ "head *+" #> <script type="text/javascript" src={libPath}></script> andThen
+ extractApiInfo(apiInfo ::= _)
+
+ Html5.write(
+ transforms(docHtml)(0),
+ new FileWriter(file),
+ stripComment = true,
+ convertAmp = false
+ )
+ }
+ }.toList.toSingleBox("Conversions failed; got errors:")
+
+ println(apiInfo)
+
+ conversionResults match {
+ case ParamFailure(message, _, _, boxes: List[_]) =>
+ val errors =
+ boxes.collect {
+ case Failure(message, _, _) => message
+ }.mkString("\n - ")
+
+ Console.err.println(s"$message\n - $errors")
+ sys.exit(errors.length)
+
+ case _ =>
+ }
+ }
+}
View
11 dexy.yaml
@@ -1,14 +1,17 @@
+ - api-docs:
+ - docs/scripts/build-api-docs.sh|bash:
+ - bash: {
+ add-new-files: True,
+ additional-doc-settings: { Output: True }
+ }
+
- html-docs:
- docs/*.adoc|asciidoctor
- example-extraction:
- docs/scripts/extract-css-selector-examples.sh|bash:
- - sh:
- timeout: 500
- html-docs
- example-verification:
- docs/scripts/run-css-selector-examples.sh|bash:
- - sh:
- timeout: 500
- example-extraction
View
12 docs/css-selectors.adoc
@@ -24,9 +24,9 @@ transforms it according to a set of rules, producing a final `NodeSeq` with all
of the transformations applied. This means a CSS Selector Transform is
ultimately simply a function with signature `(NodeSeq)=>NodeSeq`. CSS Selector
Transforms consist of three main components:
- - The selector
- - The subnode modification rule
- - The transformation function
+ * The selector
+ * The subnode modification rule
+ * The transformation function
///
Nice to have: graphic that shows a selector transform pointing to each
@@ -154,12 +154,12 @@ Benedict Cumberbatch
====
These examples show a few options:
- - You can select by element name or by class name. More available selectors are
+ * You can select by element name or by class name. More available selectors are
in the section below on <<available-selectors>>.
- - You can set the body of an element, an attribute of an element, or even
+ * You can set the body of an element, an attribute of an element, or even
replace the element altogether. More subnode modification rules are in the
section below on <<available-modification-rules>>.
- - You can combine multiple CSS selector transforms using the `&` operator. This
+ * You can combine multiple CSS selector transforms using the `&` operator. This
is subject to some limitations detailed in the section below on <<combining-selectors-and-transforms>>.
== Available Selectors
View
29 docs/scripts/build-api-docs.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+WORK_DIR=`pwd`
+
+if [[ ! -z "$DEXY_ROOT" ]]
+then
+ cd $DEXY_ROOT
+else
+ # if we're not in dexy, work in target/docs, which can be regenerated anyway
+ WORK_DIR=target/docs
+fi
+
+sbt -Dsbt.log.noformat=true doc
+
+DOCS_DIR=$WORK_DIR
+until [ "$(basename $DOCS_DIR)" == "docs" ]
+do
+ DOCS_DIR=$(dirname $DOCS_DIR)
+done
+
+for VERSION_DIR in target/scala-*/api
+do
+ SCALA_DIR=`echo $VERSION_DIR | sed -e "s/^.*\(scala-[^/]*\).*$/\1/"`
+
+ mkdir -p $DOCS_DIR/api/$SCALA_DIR
+ cp -r $VERSION_DIR/* $DOCS_DIR/api/$SCALA_DIR
+
+ sbt -Dsbt.log.noformat=true "project lift-documentation-helpers" \
+ "run-main net.liftweb.documentation.AddSearchToApiDocs \"$DOCS_DIR/api/$SCALA_DIR\""
+done

No commit comments for this range

Something went wrong with that request. Please try again.