Plain Markdown support. Directory support.
* Upgraded build common to version 1.9. * Updated the release target in build.xml to take advantage of the new features of common build 1.9. The release target now copies over the libs and release resources. * JLPMain now recognises directories in it's input list. It will add all the files in a given directory to the input list (including files in abitrarily nested subdirectories). * Abstracted the parser behavior further. Processor no longer needs to know about Parboiled ParseRunners and can use non-Parboiled parsers. * Created the JLPParser interface to support the new parser abstraction. * JLPPegParser implements the new interface trivially by creating it's own parse runner and calling it with the input given. * Added MarkdownParser, which does not actually parse the file, just creates the bare-bones SourceFile object needed for the generator to emit the Markdown contents.
This commit is contained in:
parent
9eb80e91a6
commit
1f9b6cc66d
11
build.xml
11
build.xml
@ -1,13 +1,20 @@
|
||||
<project name="Jonathan's Literate Programming" basedir="." default="release">
|
||||
|
||||
<import file="jdb-build-1.6.xml"/>
|
||||
<import file="jdb-build-1.9.xml"/>
|
||||
<property environment="env"/>
|
||||
<property file="project.properties"/>
|
||||
|
||||
<target name="release" depends="build">
|
||||
<mkdir dir="${release.dir}/lib"/>
|
||||
<copy file="${build.dir}/${name}-${version}.${build.number}.jar"
|
||||
tofile="${release.dir}/${name}-${version}.jar"/>
|
||||
<copy file="${basedir}/jlp" todir="${release.dir}"/>
|
||||
<copy todir="${release.dir}">
|
||||
<fileset dir="${resources.dir}/release"/>
|
||||
</copy>
|
||||
<copy todir="${release.dir}/lib">
|
||||
<fileset dir="${build.dir}/lib/runtime/jar"/>
|
||||
</copy>
|
||||
|
||||
</target>
|
||||
|
||||
</project>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project name="Jonathan Bernard Build Common">
|
||||
<project name="Jonathan Bernard Build Common"
|
||||
xmlns:ivy="antlib:org.apache.ivy.ant">
|
||||
|
||||
<property environment="env"/>
|
||||
|
||||
@ -16,6 +17,7 @@
|
||||
<property name="build.dir" value="${basedir}/build"/>
|
||||
<property name="lib.dir" value="${basedir}/lib"/>
|
||||
<property name="resources.dir" value="${basedir}/resources"/>
|
||||
<property name="splash.image" value="splash.png"/>
|
||||
|
||||
<!--======== PATHS ========-->
|
||||
<path id="groovy.classpath">
|
||||
@ -59,9 +61,25 @@
|
||||
</target>
|
||||
|
||||
<!--======== LIBRARY TARGETS ========-->
|
||||
<target name="lib" depends="-lib-local,-lib-ivy"/>
|
||||
<target name="-lib" depends="-lib-local,-lib-ivy,lib"/>
|
||||
|
||||
<target name="lib"/>
|
||||
|
||||
<target name="-lib-ivy" unless="${lib.local}"/>
|
||||
<target name="-init-ivy">
|
||||
<ivy:settings id="ivy.settings" file="ivysettings.xml"/>
|
||||
</target>
|
||||
|
||||
<target name="-lib-ivy" depends="-init-ivy" unless="${lib.local}">
|
||||
<ivy:retrieve settingsRef="ivy.settings"
|
||||
pattern="${lib.dir}/[conf]/[type]/[artifact]-[revision].[ext]"
|
||||
conf="compile,runtime"/>
|
||||
</target>
|
||||
|
||||
<target name="-lib-groovy" if="${lib.local}">
|
||||
<copy todir="${build.dir}/lib/runtime/jar">
|
||||
<fileset dir="${env.GROOVY_HOME}/embeddable"/>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="-lib-local" if="${lib.local}">
|
||||
<echo message="Resolving libraries locally."/>
|
||||
@ -96,7 +114,7 @@
|
||||
</target>
|
||||
|
||||
<!--======== COMPILATION TARGETS ========-->
|
||||
<target name="-compile-groovy" depends="-init,-init-groovy,lib">
|
||||
<target name="-compile-groovy" depends="-init,-init-groovy,-lib,-lib-groovy">
|
||||
<mkdir dir="${build.dir}/main/classes"/>
|
||||
<groovyc srcdir="${src.dir}/main" destdir="${build.dir}/main/classes"
|
||||
includeAntRuntime="false">
|
||||
@ -109,7 +127,7 @@
|
||||
</groovyc>
|
||||
</target>
|
||||
|
||||
<target name="-compile-java" depends="-init,lib">
|
||||
<target name="-compile-java" depends="-init,-lib">
|
||||
<mkdir dir="${build.dir}/main/classes"/>
|
||||
<javac srcdir="${src.dir}/main" destdir="${build.dir}/main/classes"
|
||||
includeAntRuntime="false" classpathref="compile-libs"/>
|
||||
@ -178,13 +196,42 @@
|
||||
</target>
|
||||
|
||||
<!--======== BUILD TARGETS ========-->
|
||||
<target name="-build-modular"
|
||||
<target name="-build-modular-lib" unless="executable.jar"
|
||||
depends="compile,increment-build-number,resources">
|
||||
|
||||
<jar destfile="${build.dir}/${name}-${version}.${build.number}.jar"
|
||||
basedir="${build.dir}/main/classes"/>
|
||||
</target>
|
||||
|
||||
<target name="-build-modular-executable" if="executable.jar"
|
||||
depends="compile,increment-build-number,resources">
|
||||
|
||||
<pathconvert property="jar.classpath" pathsep=" " refid="runtime-libs">
|
||||
<mapper>
|
||||
<chainedmapper>
|
||||
<!-- remove absolute path -->
|
||||
<flattenmapper />
|
||||
|
||||
<!-- add lib/ prefix -->
|
||||
<globmapper from="*" to="lib/*" />
|
||||
</chainedmapper>
|
||||
</mapper>
|
||||
</pathconvert>
|
||||
|
||||
<jar destfile="${build.dir}/${name}-${version}.${build.number}.jar"
|
||||
basedir="${build.dir}/main/classes">
|
||||
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="${main.class}"/>
|
||||
<attribute name="Class-Path" value="${jar.classpath}"/>
|
||||
<attribute name="SplashScreen-Image" value="${splash.image}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="-build-modular"
|
||||
depends="-build-modular-lib,-build-modular-executable"/>
|
||||
|
||||
<target name="-build-packed-libs"
|
||||
depends="compile,increment-build-number,resources">
|
||||
|
@ -1,6 +1,8 @@
|
||||
#Sun, 25 Dec 2011 21:56:17 -0600
|
||||
#Sun, 25 Dec 2011 23:07:02 -0600
|
||||
name=jlp
|
||||
version=1.0
|
||||
build.number=0
|
||||
version=1.1
|
||||
build.number=6
|
||||
lib.local=true
|
||||
release.dir=release
|
||||
main.class=com.jdblabs.jlp.JLPMain
|
||||
executable.jar=true
|
||||
|
@ -73,19 +73,27 @@ public class JLPMain {
|
||||
|
||||
// get files passed in
|
||||
def filenames = opts.getArgs()
|
||||
def inputFiles = (filenames.collect { filename ->
|
||||
def inputFiles = []
|
||||
|
||||
filenames.each { filename ->
|
||||
// create a File object
|
||||
File file = new File(filename)
|
||||
|
||||
File file = new File(filename)
|
||||
|
||||
// if this is a relative path, resolve it against our path root
|
||||
if (!file.isAbsolute()) { file = new File(pathRoot, filename) }
|
||||
|
||||
// warn the user about files that do not exist
|
||||
if (!file.exists()) {
|
||||
System.err.println
|
||||
"'${file.canonicalPath}' does not exist: ignored." }
|
||||
|
||||
return file }).findAll { it.exists() }
|
||||
// if this file does not exist, warn the user and skip it
|
||||
if (!file.exists()) {
|
||||
System.err.println(
|
||||
"'${file.canonicalPath}' does not exist: ignored.")
|
||||
return }
|
||||
|
||||
// if this file is a directory, add all the files in it (recurse
|
||||
// into sub-directories and add their contents as well).
|
||||
if (file.isDirectory()) { file.eachFileRecurse {
|
||||
if (it.isFile()) { inputFiles << it }}}
|
||||
|
||||
else { inputFiles << file } }
|
||||
|
||||
Processor.process(outputDir, css, inputFiles)
|
||||
}
|
||||
|
6
src/main/com/jdblabs/jlp/JLPParser.java
Normal file
6
src/main/com/jdblabs/jlp/JLPParser.java
Normal file
@ -0,0 +1,6 @@
|
||||
package com.jdblabs.jlp;
|
||||
|
||||
import com.jdblabs.jlp.ast.SourceFile;
|
||||
|
||||
public interface JLPParser {
|
||||
public SourceFile parse(String input); }
|
@ -8,9 +8,10 @@ import org.parboiled.BaseParser;
|
||||
import org.parboiled.Context;
|
||||
import org.parboiled.Rule;
|
||||
import org.parboiled.annotations.*;
|
||||
import org.parboiled.parserunners.ReportingParseRunner;
|
||||
|
||||
@BuildParseTree
|
||||
public class JLPPegParser extends BaseParser<Object> {
|
||||
public class JLPPegParser extends BaseParser<Object> implements JLPParser {
|
||||
|
||||
int curLineNum = 1;
|
||||
|
||||
@ -31,6 +32,10 @@ public class JLPPegParser extends BaseParser<Object> {
|
||||
public JLPPegParser() {
|
||||
this("/**", "*/", "!#$%^&*()_-=+|;:'\",<>?~`", "///"); }
|
||||
|
||||
public SourceFile parse(String input) {
|
||||
ReportingParseRunner rpr = new ReportingParseRunner(this.SourceFile());
|
||||
return (SourceFile) rpr.run(input).resultValue; }
|
||||
|
||||
/**
|
||||
* Parses the rule:
|
||||
* SourceFile = (Block / DocBlock / CodeBlock)+
|
||||
|
20
src/main/com/jdblabs/jlp/MarkdownParser.groovy
Normal file
20
src/main/com/jdblabs/jlp/MarkdownParser.groovy
Normal file
@ -0,0 +1,20 @@
|
||||
package com.jdblabs.jlp
|
||||
|
||||
import com.jdblabs.jlp.ast.*
|
||||
|
||||
public class MarkdownParser implements JLPParser {
|
||||
|
||||
public SourceFile parse(String input) {
|
||||
|
||||
def sourceFile = new SourceFile()
|
||||
def block
|
||||
def docBlock = new DocBlock(0)
|
||||
def codeBlock = new CodeBlock(0)
|
||||
def docText = new DocText(0)
|
||||
|
||||
docText.value = input
|
||||
docBlock.docTexts << docText
|
||||
block = new Block(codeBlock, docBlock, 0)
|
||||
sourceFile.blocks << block
|
||||
|
||||
return sourceFile }}
|
@ -2,7 +2,6 @@ package com.jdblabs.jlp
|
||||
|
||||
import org.parboiled.BaseParser
|
||||
import org.parboiled.Parboiled
|
||||
import org.parboiled.parserunners.ReportingParseRunner
|
||||
|
||||
/**
|
||||
* Processor processes one batch of input files to create a set of output files.
|
||||
@ -22,7 +21,7 @@ public class Processor {
|
||||
// shortcut for docs[currentDocId]
|
||||
public TargetDoc currentDoc
|
||||
|
||||
protected Map<String, BaseParser> parsers = [:]
|
||||
protected Map<String, JLPParser> parsers = [:]
|
||||
protected Map<String, JLPBaseGenerator> generators = [:]
|
||||
|
||||
public static void process(File outputDir, String css,
|
||||
@ -61,11 +60,9 @@ public class Processor {
|
||||
// TODO: add logic to configure or autodetect the correct parser for
|
||||
// each file
|
||||
def parser = getParser(sourceTypeForFile(currentDoc.sourceFile))
|
||||
def parseRunner = new ReportingParseRunner(parser.SourceFile())
|
||||
|
||||
// TODO: error detection
|
||||
currentDoc.sourceAST = parseRunner.run(
|
||||
currentDoc.sourceFile.text).resultValue }
|
||||
currentDoc.sourceAST = parser.parse(currentDoc.sourceFile.text) }
|
||||
|
||||
// run our generator parse phase (first pass over the ASTs)
|
||||
processDocs {
|
||||
@ -175,6 +172,7 @@ public class Processor {
|
||||
case 'groovy': return 'groovy';
|
||||
case 'java': return 'java';
|
||||
case 'js': return 'javascript';
|
||||
case 'md': return 'markdown';
|
||||
default: return 'unknown'; }}
|
||||
|
||||
protected getGenerator(String sourceType) {
|
||||
@ -187,13 +185,14 @@ public class Processor {
|
||||
return generators[sourceType] }
|
||||
|
||||
protected getParser(String sourceType) {
|
||||
println "Looking for a ${sourceType} parser."
|
||||
if (parsers[sourceType] == null) {
|
||||
switch(sourceType) {
|
||||
case 'erlang':
|
||||
parsers[sourceType] = Parboiled.createParser(
|
||||
JLPPegParser, '%%')
|
||||
println "Built an erlang parser."
|
||||
break
|
||||
case 'markdown':
|
||||
parsers[sourceType] = new MarkdownParser()
|
||||
break
|
||||
case 'c':
|
||||
case 'c++':
|
||||
@ -203,7 +202,6 @@ public class Processor {
|
||||
default:
|
||||
parsers[sourceType] = Parboiled.createParser(JLPPegParser,
|
||||
'/**', '*/', '!#$%^&*()_-=+|;:\'",<>?~`', '///')
|
||||
println "Built a java parser."
|
||||
break }}
|
||||
|
||||
return parsers[sourceType] }
|
||||
|
Loading…
Reference in New Issue
Block a user