Skip to content

Commit

Permalink
[#1660] Add support for project documentation in docviewer plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
marekpiechut authored and Notalifeform committed Apr 21, 2013
1 parent 2df91dc commit 0b12575
Show file tree
Hide file tree
Showing 16 changed files with 625 additions and 29 deletions.
2 changes: 2 additions & 0 deletions documentation/manual/firstapp.textile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ The @play new@ command creates a new directory @helloworld/@ and populates it wi

@conf/@ contains all the application’s configuration files, especially the main @application.conf@ file, the @routes@ definition files and the @messages@ files used for internationalization.

@documentation/@ contains application documentation. You can add your project specific documentation there and access it by "@projectdocs":http://localhost:9000/@projectdocs url.

@lib/@ contains all optional Java libraries packaged as standard .jar files.

@public/@ contains all the publicly available resources, which includes JavaScript, stylesheets and images directories.
Expand Down
10 changes: 10 additions & 0 deletions documentation/manual/main.textile
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,16 @@ h3. The lib directory

This directory contains all standard Java libraries needed by your application. They are automatically added to the Java classpath.

h3. The documentation directory

This directory can include any project documentation you want to share with fellow developers.
You can add documentation sections using "textile":http://en.wikipedia.org/wiki/Textile_%28markup_language%29 markup.

Every textile file in documentation folder will automatically be added to your documentation index. Just make sure you start it with some @h1.@ header, as it's being used as chapter name.

You can customize the way documentation looks by editing @template.html@ file, but it's not mandatory and you can remove it if plain black on white page is ok for you.

When you want to share it with non technical staff, or need to check it out without Play app running there's a export functionality. Just execute play @doc:export@ command in project root. This will generate zip file in @documentation@ folder with all your textile files rendered to html and files from @images@ and @files@ directories included.

h2. <a name="lifecycle">Development life cycle</a>

Expand Down
1 change: 1 addition & 0 deletions framework/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
<property name="play.path" value="../.."/>
<ant antfile="build.xml" target="build" dir="../modules/testrunner" />
<ant antfile="build.xml" target="build" dir="../modules/grizzly" />
<ant antfile="build.xml" target="build" dir="../modules/docviewer" />
</target>

<!-- Netbeans support -->
Expand Down
4 changes: 4 additions & 0 deletions framework/pym/play/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ def readConfs(self, key):

def modules(self):
modules = []
if self.readConf('application.mode').lower() == 'dev':
#Load docviewer module
modules.append(os.path.normpath(os.path.join(self.play_env["basedir"], 'modules/docviewer')))

for m in self.readConfs('module.'):
if '${play.path}' in m:
m = m.replace('${play.path}', self.play_env["basedir"])
Expand Down
4 changes: 4 additions & 0 deletions modules/docviewer/app/DocViewerPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ public void onRoutesLoaded() {
Router.prependRoute("GET", "/@documentation/modules/{module}/files/{name}", "PlayDocumentation.file");
Router.prependRoute("GET", "/@documentation/cheatsheet/{category}", "PlayDocumentation.cheatSheet");
Router.prependRoute("GET", "/@documentation/{docLang}/cheatsheet/{category}", "PlayDocumentation.cheatSheet");
Router.prependRoute("GET", "/@projectdocs/?", "ProjectDocumentation.index");
Router.prependRoute("GET", "/@projectdocs/{id}", "ProjectDocumentation.page");
Router.prependRoute("GET", "/@projectdocs/images/{name}", "ProjectDocumentation.image");
Router.prependRoute("GET", "/@projectdocs/files/{name}", "ProjectDocumentation.file");
}

}
46 changes: 17 additions & 29 deletions modules/docviewer/app/controllers/PlayDocumentation.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package controllers;

import helpers.CheatSheetHelper;

import helpers.LangMenuHelper;
import helpers.LangMenuHelper.*;
import play.Logger;
import helpers.LangMenuHelper.LangMenu;
import play.Play;
import play.libs.IO;
import play.modules.docviewer.DocumentationGenerator;
import play.mvc.Controller;
import play.mvc.Http;
import play.vfs.VirtualFile;
Expand All @@ -16,20 +15,24 @@
import java.util.List;
import java.util.Map;


public class PlayDocumentation extends Controller {

public static DocumentationGenerator generator = new DocumentationGenerator();

public static void index() throws Exception {
Http.Header header = request.headers.get("accept-language");
String docLang = header!=null? header.value().split(",")[0] : "";
docLang = docLang.length()>2? docLang.substring(0,2) : docLang;
String docLang = header != null ? header.value().split(",")[0] : "";
docLang = docLang.length() > 2 ? docLang.substring(0, 2) : docLang;
page("home", null, docLang);
}

public static void page(String id, String module, String docLang) throws Exception {
String docLangDir = (docLang != null && (!"en".equalsIgnoreCase(docLang) && !docLang.matches("en-.*") ) ) ? "_" + docLang + "/" : "/";
String docLangDir = (docLang != null && (!"en".equalsIgnoreCase(docLang) && !docLang.matches(
"en-.*"))) ? "_" + docLang + "/" : "/";

File page = new File(Play.frameworkPath, "documentation/manual" + docLangDir + id + ".textile");
if(!page.exists()){
if (!page.exists()) {
page = new File(Play.frameworkPath, "documentation/manual/" + id + ".textile");
}

Expand All @@ -41,8 +44,9 @@ public static void page(String id, String module, String docLang) throws Excepti
notFound("Manual page for " + id + " not found");
}
String textile = IO.readContentAsString(page);
String html = toHTML(textile);
String title = getTitle(textile);
String html = generator.toHTML(textile);
html = generator.stripBody(html);
String title = generator.getTitle(textile);

List<String> modules = new ArrayList();
List<String> apis = new ArrayList();
Expand All @@ -62,17 +66,15 @@ public static void page(String id, String module, String docLang) throws Excepti
render(id, html, title, modules, apis, module, docLang, langMenuList);
}





public static void cheatSheet(String category, String docLang) {
File[] sheetFiles = CheatSheetHelper.getSheets(category, docLang);
if (sheetFiles != null) {
List<String> sheets = new ArrayList<String>();

for (File file : sheetFiles) {
sheets.add(toHTML(IO.readContentAsString(file)));
String html = generator.toHTML(IO.readContentAsString(file));
html = generator.stripBody(html);
sheets.add(html);
}

String title = CheatSheetHelper.getCategoryTitle(category);
Expand Down Expand Up @@ -104,18 +106,4 @@ public static void file(String name, String module, String lang) {
}
renderBinary(file);
}

static String toHTML(String textile) {
String html = new jj.play.org.eclipse.mylyn.wikitext.core.parser.MarkupParser(new jj.play.org.eclipse.mylyn.wikitext.textile.core.TextileLanguage()).parseToHtml(textile);
html = html.substring(html.indexOf("<body>") + 6, html.lastIndexOf("</body>"));
return html;
}

static String getTitle(String textile) {
if (textile.length() == 0) {
return "";
}
return textile.split("\n")[0].substring(3).trim();
}

}
}
54 changes: 54 additions & 0 deletions modules/docviewer/app/controllers/ProjectDocumentation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package controllers;

import play.modules.docviewer.DocumentationGenerator;
import play.mvc.Controller;

import java.io.File;

/**
* Controller to render project documentation.
* Allows to embed textile docs inside project and access it via browser
* in development mode.
*
* @author Marek Piechut
*/
public class ProjectDocumentation extends Controller {

public static DocumentationGenerator generator = new DocumentationGenerator();

public static void index() throws Exception {
String indexHtml = generator.generateIndex();

//We need trailing slash or links won't work
if (!request.url.endsWith("/")) {
redirect(request.url + "/");
}
renderHtml(indexHtml);
}

public static void page(String id) {
String html = generator.generatePage(id);
if (html == null) {
notFound("Documentation page for " + id + " not found");
}
renderHtml(html);
}


public static void file(String name) {
File file = new File(generator.projectDocsPath, "files/" + name);
if (!file.exists()) {
notFound();
}
renderBinary(file);
}

public static void image(String name) {
File image = new File(generator.projectDocsPath, "images/" + name);

if (!image.exists()) {
notFound();
}
renderBinary(image);
}
}
39 changes: 39 additions & 0 deletions modules/docviewer/build.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>

<project name="Docviewer" default="build" basedir=".">

<path id="project.classpath">
<pathelement path="${play.path}/framework/classes"/>
<fileset dir="${play.path}/framework/lib">
<include name="*.jar"/>
</fileset>
</path>

<target name="build" depends="compile">

<copy todir="tmp/classes">
<fileset dir="src">
<include name="**/*.properties"/>
<include name="**/*.xml"/>
<include name="**/play.plugins"/>
<include name="**/play.static"/>
</fileset>
</copy>
<jar destfile="lib/play-docviewer.jar" basedir="tmp/classes">
<manifest>
<section name="Play">
<attribute name="Specification-Title" value="Docviewer"/>
</section>
</manifest>
</jar>
<delete dir="tmp" />
</target>

<target name="compile">
<mkdir dir="tmp/classes" />
<javac srcdir="src" destdir="tmp/classes" source="1.6" target="1.6" debug="true">
<classpath refid="project.classpath" />
</javac>
</target>

</project>
47 changes: 47 additions & 0 deletions modules/docviewer/commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Here you can create play commands that are specific to the module, and extend existing commands
import os, os.path
import getopt
import sys
import subprocess

MODULE = 'docviewer'

# Commands that are specific to your module

COMMANDS = ['doc:export']

def execute(**kargs):
command = kargs.get("command")
app = kargs.get("app")
args = kargs.get("args")
env = kargs.get("env")

if command == "doc:export":
print "~ Generating project documentation"
print "~ "
java_cmd = app.java_cmd([], None, "play.modules.docviewer.ExportDocumentationGenerator", args)
try:
subprocess.call(java_cmd, env=os.environ)
except OSError:
print "Could not execute the java executable, please make sure the JAVA_HOME environment variable is set properly (the java executable should reside at JAVA_HOME/bin/java). "
sys.exit(-1)
print

# This will be executed before any command (new, run...)
def before(**kargs):
command = kargs.get("command")
app = kargs.get("app")
args = kargs.get("args")
env = kargs.get("env")


# This will be executed after any command (new, run...)
def after(**kargs):
command = kargs.get("command")
app = kargs.get("app")
args = kargs.get("args")
env = kargs.get("env")

if command == "new":
pass

Loading

0 comments on commit 0b12575

Please sign in to comment.