PK N`j?5+S S build.xml
PK vF@Yli" " manifestversion=1.6
frameworkVersions=1.2
PK vF@A|0u u Readme.md#Markdown module for the play framework
##What is markdown ?
Markdown is a text-to-HTML filter; it translates an easy-to-read / easy-to-write structured text
format into HTML. Markdown's text format is most similar to that of plain text email, and supports
features such as headers, *emphasis*, code blocks, blockquotes, and links.
##What does the module provide ?
The module provides 3 integration points:
1. First, a groovy page java extension ${str.markdown().raw()}
2. A basic controller to quickly serve your markdown contents, extend to your likings.
3. Last but not least, a powerful developer API with support for streams and markdown document trees.
##How is this markdown module better than others ?
The module is based on the excellent [markdownPapers](https://github.com/lruiz/MarkdownPapers) project which not only shines by its speed (4x faster than the nearest competitor), but also by its design:
Based on JavaCC, the markdown parser can work with streams and build a markdown document tree. The tree can be processed using a Visitor pattern. It's a great way to enhance the markdown grammar with your own extensions.
Overall, MarkdownPaper is faster and uses less memory than any of its Java competitors.
##Usage:
### Groovy page
Probably the easiest way to add markdown contents on a page:
${"**Hello** *world*".markdown().raw()}
### Controller
Add the following to the conf/route
GET /docs/images/{imageName}\.{ext} MarkdownController.image
GET /docs/{page}\.md MarkdownController.transform
Ensure the markdown pages are located in
*. public/mddocs/*.md -for the documents
*. public/mddocs/images/ -for the images
Now access the page using `http://localhost:9000/docs/intro.md`
PS: You may extend the controller and implement new actions that better fit your preferences.
### API
The utility class `markdown.Markdown` provide two generic methods:
public static String transformMarkdown(String markdown) throws java.text.ParseException;
public static String transformMarkdown(Reader markdownReader) throws java.text.ParseException;
Should you need to handle a markdown document tree by your own, you will need to use the native package **org.tautua.markdownpapers.Markdown**
Reader in = new FileReader("in.md");
Visitor v = new HtmlEmitter();
Parser parser = new Parser(in);
Document doc = parser.parse();
doc.accept(v);
## Sample application
Part of the distribution
## Credits
markdownPapers - Larry Ruiz - [https://github.com/lruiz/MarkdownPapers](https://github.com/lruiz/MarkdownPapers)
play-markdown module - Olivier Refalo - [https://github.com/orefalo](https://github.com/orefalo)
## History
Version 1.6: markdownPaper upgraded to v1.2.6
Version 1.5 : fixed: deploying in prod mode fails compilation
Version 1.4 : markdownPaper upgraded to v1.2.5
Version 1.3 : markdownPaper upgraded to v1.2.4
PK Am?s]! ! ' app/controllers/MarkdownController.javapackage controllers;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import markdown.Markdown;
import play.Play;
import play.mvc.Controller;
public class MarkdownController extends Controller {
private static final String IMAGE_LOCATION = "public/mddocs/images/";
private static final String DOCUMENT_LOCATION = "public/mddocs/";
public static void transform(String page) throws Exception {
// Just a little validation to make sure the path is not forged
if (page == null || page.indexOf('/') > 0 || page.indexOf('\\') > 0
|| page.indexOf('.') > 0)
throw new IOException("Invalid path:"+page);
File f = new File(Play.applicationPath, DOCUMENT_LOCATION + page
+ ".md");
if (!f.exists()) {
notFound("Markdown page for " + page + " not found");
}
Reader pageReader = new FileReader(f);
String html = Markdown.transformMarkdown(pageReader);
render(html);
}
public static void image(String imageName, String ext) throws Exception {
// Just a little validation to make sure the path is not forged
if (imageName == null || imageName.indexOf('/') > 0
|| imageName.indexOf('\\') > 0 || imageName.indexOf('.') > 0)
throw new IOException("Invalid path:"+imageName);
if (ext == null || ext.indexOf('/') > 0 || ext.indexOf('\\') > 0
|| ext.indexOf('.') > 0)
throw new IOException("Invalid path:"+ext);
File image = new File(Play.applicationPath, IMAGE_LOCATION + imageName
+ '.' + ext);
if (!image.exists()) {
notFound();
}
renderBinary(image);
}
}
PK N`j?T-I app/ext/MarkdownExtensions.javapackage ext;
/**
* Basic groovy server page extension for markdown
*
* Usage: ${"**Hello** *world*".markdown().raw()}
*
* @author olivier refalo
*/
import java.text.ParseException;
import markdown.Markdown;
import play.templates.JavaExtensions;
public class MarkdownExtensions extends JavaExtensions {
public static String markdown(Object mdString) {
try {
return Markdown.transformMarkdown(mdString.toString());
} catch (ParseException e) {
return e.toString();
}
}
}
PK N`j?e
A app/markdown/Markdown.javapackage markdown;
/*
* Copyright 2011 gitblit.com.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import org.tautua.markdownpapers.parser.ParseException;
/**
* Utility methods for transforming raw markdown text to html.
*
* @author James Moger
*
*/
public class Markdown {
private Markdown() {
// this is a utility class, it cannot be instantiated
}
/**
* Returns the html version of the markdown source text.
*
* @param markdown
* @return html version of markdown text
* @throws java.text.ParseException
*/
public static String transformMarkdown(String markdown)
throws java.text.ParseException {
try {
StringReader reader = new StringReader(markdown);
String html = transformMarkdown(reader);
reader.close();
return html;
} catch (NullPointerException p) {
throw new java.text.ParseException("Markdown string is null!", 0);
}
}
/**
* Returns the html version of the markdown source reader. The reader is
* closed regardless of success or failure.
*
* @param markdownReader
* @return html version of the markdown text
* @throws java.text.ParseException
*/
public static String transformMarkdown(Reader markdownReader)
throws java.text.ParseException {
// Read raw markdown content and transform it to html
StringWriter writer = new StringWriter();
try {
org.tautua.markdownpapers.Markdown md = new org.tautua.markdownpapers.Markdown();
md.transform(markdownReader, writer);
return writer.toString().trim();
} catch (ParseException p) {
throw new java.text.ParseException(p.getMessage(), 0);
} finally {
try {
writer.close();
} catch (IOException e) {
// IGNORE
}
}
}
}
PK N`j?6Nc c + app/views/MarkdownController/transform.html#{extends 'main.html' /}
#{stylesheet 'markdown.css' /}
${html.raw()}
PK N`j? conf/application.confPK vF@$/m m conf/dependencies.ymlself: play -> markdown 1.6
require:
- play
- org.tautua.markdownpapers -> markdownpapers-core 1.2.6
PK N`j?W
conf/messages# Default play-markdown messages
# You can specialize this file for each language.
# For exemple, for french create a messages.fr file
#play-markdown.name=play-markdownPK N`j?F conf/routes# This file defines all module routes (Higher priority routes first)
#
# import these routes in the main app as :
# * / module:play-markdown
#
# ~~~~
GET /? Module.indexPK N`j?Vh ! documentation/manual/home.textile
Hey, you don't expect the doc to be written in Textile, right ?
"Markdown module documentation":http://www.github.com/orefalo/markdown
PK Am?|DžCU CU ! lib/markdownpapers-core-1.2.5.jarPK XcS? META-INF/MANIFEST.MF R[O0~_yBy5u-аK9{ذb̂.;axk4"F!\gz(2ނd{e1j
LEpAԞZ &U:*M %Qa:QO !ז\'xn\UuVR1JBOH*AsIg}HL#$َ J"\X5Thm=#E3Ka|8ο#P(""
~D2{}I<_fZXKv}u PKc)k < PK XcS? META-INF/ PK PK XcS? META-INF/maven/ PK PK XcS? ) META-INF/maven/org.tautua.markdownpapers/ PK PK XcS? = META-INF/maven/org.tautua.markdownpapers/markdownpapers-core/ PK PK XcS? K META-INF/maven/org.tautua.markdownpapers/markdownpapers-core/pom.propertiesU̻!@ў ډ5VBYEd/vX#;F0QokrG]:"N*M"R)$~qh߱`-<s Mi,Lb_PK PK vQ? D META-INF/maven/org.tautua.markdownpapers/markdownpapers-core/pom.xmlVrF}+:zɥIY[Pe }F+hgF\>=a_0gvd)Pi.ŭ:dErL'ߝwa+u[ w2*,:n&doG(4PB?g}+ѨQu
pc?`h:p2F`4o?ۀ4(J\Hn
9F|#K$KI"2-ʋ)J3n)-'M4ZA#8o3BQ'i_{ymZ_^}|\hcA4ѥAFeYoH]]|x;a) 'B wZ"Cdy`^ԗXEhh:!ȐV8]ذ_ PR+|bfz_Esy4?W
LƘlXN(ljBÑTx.9^8#mh[*``Oe0T6X@ iA!ROVh/K@jKbQVb4S{Bqn0*ʫw<4K*fN
|PagaFtiVv>!n_l8DRyR(v~+VEоg1ps%QKջdZc(Ay*E/4:=h[osL[]ow}Y:
\K"p-J&ʸO/
{F#{/b̑Zqe:I_nΰ^gy+tu@O0
ZW{]lRvE~2 PK)'X
PK XcS? org/ PK PK XcS? org/tautua/ PK PK XcS? org/tautua/markdownpapers/ PK PK TcS? - org/tautua/markdownpapers/HtmlEmitter$1.classSn@=q\--B/.( DIS5I>Tguȗg@B~ uP
HZ;3gvzfg 6<2H^E x C)*ΩZ&?CG?{<h<c8h0_XKdϠԼ>mΙ+ZѨ'.9ɛŝ}q&;Ephy}3vBnlNj|Kڒ#CK&^w-lwXVQPc
Y\ӰU
kXgX8C*CjcLjc[0h
~A yvHX!TG+]Q&*uHިT+0PS٨1]1Pr'uܡnL[;Or"o
m"Y }@,7/H|_+ʛΜC`*(<[2=#TL"
o O