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:
@ -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] }
|
||||
|
Reference in New Issue
Block a user