Starting work on the generation/emitter phase.

This commit is contained in:
Jonathan Bernard 2011-08-29 09:46:04 -05:00
parent 557feaeb83
commit b8a47cac7e
7 changed files with 164 additions and 0 deletions

View File

@ -0,0 +1,13 @@
package com.jdblabs.jlp
import com.jdblabs.jlp.ast.*
public class EchoEmitter extends JLPEmitter {
public String emitAuthor(String value) { "Author: $value" }
public String emitDoc(String value) { value }
public String emitExample(String value) { "Example:\n$value" }
public String emitOrg(String value) { "Org: $value" }
public String emitBlock(TextBlock textBlock) { textBlock.value }
}

View File

@ -0,0 +1,7 @@
package com.jdblabs.jlp
public interface Formatter {
String formatText(String text)
String formatCode(String code)
String formatReference(String ref) }

View File

@ -0,0 +1,46 @@
package com.jdblabs.jlp
import com.jdblabs.jlp.ast.*
import com.jdblabs.jlp.ast.Directive.DirectiveType
import org.slf4j.Logger
import org.slf4j.LoggerFactory
public class FormattingEmitter extends JLPBaseEmitter {
Formatter formatter
private Logger log = LoggerFactory.getLogger(this.getClass())
public FormattingEmitter(Formatter f, def generationState) {
super(generationState)
this.formatter = f }
protected String emit(TextBlock textBlock) {
return formatter.format(textBlock) }
protected String emit(Directive directive) {
switch (directive.type) {
case DirectiveType.Author:
case DirectiveType.Doc:
case DirectiveType.Example:
case DirectiveType.Org:
def orgValue = directive.value
if generationState.orgs.contains(orgValue) {
log.warn("Duplicate @org id: '${orgValue}'.")
def orgMatcher = (orgValue =~ /(.*)-(\d+)/
if (orgMatcher.matches()) {
orgValue = "${m[0][1]}-${(m[0][2] as int) + 1}" }
else { orgValue += "-1" } }
generationState.orgs << orgValue
formatter.formatReference(orgValue)
break } }
private formatText(String s) {
// fix links to internal targets
s = s.eachMatch(/jlp:\/\/([^\s]+)/, s)
// format with formatter
return formatter.formatText(s)
}
}

View File

@ -0,0 +1,52 @@
package com.jdblabs.jlp
import com.jdblabs.jlp.ast.*
import com.jdblabs.jlp.ast.Directive.DirectiveType
public abstract class JLPBaseEmitter {
def generationState
public JLPBaseEmitter(def generationState) {
this.generationState = generationState }
public String emitDocument(List<ASTNode> sourceNodes) {
StringBuilder result =
sourceNodes.inject(new StringBuilder()) { sb, node ->
sb.append(emit(node, generationState))
return sb }
return result.toString() }
protected String emit(DocBlock docBlock) {
List printQueue
StringBuilder result
printQueue = docBlock.directives.collect { directive ->
def queueItem = [line: directive.lineNumber, value: directive]
switch (direcive.type) {
case DirectiveType.Author: queueItem.priority = 90; break
case DirectiveType.Doc: queueItem.priority = 50; break
case DirectiveType.Example: queueItem.priority = 50; break
case DirectiveType.Org: queueItem.priority = 10; break
return queueItem }
printQueue.addAll(docBlock.textBlocks.collect { textBlock ->
[ priority: 50, line: textBlock.lineNumber, value: textBlock ] }
// sort by priority, then by line number
printQueue.sort(
{i1, i2 -> i1.priority != i2.priority ?
i1.priority - i2.priority :
i1.line - i2.line} as Comparator)
result = printQueue.inject(new StringBuilder()) { sb, printable ->
sb.append(emit(printable.value))
return sb }
return result.toString() }
protected abstract String emit(TextBlock textBlock)
protected abstract String emit(Directive directive)
}

View File

@ -0,0 +1,23 @@
package com.jdblabs.jlp
import com.jdblabs.jlp.ast.*
import org.pegdown.PegDownParser
public class MarkdownEmitter extends JLPEmitter {
protected MarkdownEmitter() {}
def pegdown = new PegDownParser()
protected String emitAuthor(String value) {
'<span class="author">${value}</span>' }
protected String emitDoc(String value) { /* parse as MD */ }
protected String emitExample(String value) {/* parse as MD */ }
protected String emitOrg(String value) { }
protected String emitBlock(TextBlock textBlock) { "todo" }
}

View File

@ -0,0 +1,16 @@
package com.jdblabs.jlp
public class MarkdownFormatter implements Formatter {
private PegDownProcessor pegdown
public MarkdownFormatter() {
pegdown = new PegDownProcessor() }
public String formatText(String s) { pegdown.markdownToHtml(s) }
public String formatCode(String s) {
pegdown.markdownToHtml(s.replaceAll(/(^|\n)/, /$1 /)) }
public String formatReference(String s) { '<a name="${s}"/>' }
}

View File

@ -0,0 +1,7 @@
package com.jdblabs.jlp
public class TransparentFormatter implements Formatter {
public String formatText(String text) { return text }
public String formatCode(String code) { return code }
public String formatReference(String ref) { return "ref#${ref}" } }