Created
February 25, 2011 10:23
-
-
Save Riduidel/843613 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.io.File | |
| import groovy.xml.MarkupBuilder | |
| abstract class Entry { | |
| /** parent documentor, used to access doc various formats */ | |
| def doc; | |
| /** node name */ | |
| def name; | |
| /** Comments to be kept at last */ | |
| def finalComments; | |
| /** current comments */ | |
| def comments = [:] | |
| def currentFormatting = null | |
| def add(String line) { | |
| if(line.startsWith(doc.docStart)) { | |
| def content = line.substring(line.indexOf(doc.docStart)+doc.docStart.length()).trim() | |
| def newFormatting = doc.formattings.find { f -> | |
| content.contains(f) | |
| } | |
| if(newFormatting!=null) { | |
| currentFormatting = newFormatting | |
| } | |
| if(content.indexOf(currentFormatting)>=0) { | |
| content = content.substring(content.indexOf(currentFormatting)+currentFormatting.length()) | |
| } | |
| if(comments.containsKey(currentFormatting)) { | |
| comments[currentFormatting]= (comments[currentFormatting]==null ? content : (comments[currentFormatting]==false ? content : comments[currentFormatting]+"\n"+content)) | |
| } else { | |
| comments[currentFormatting]= content.size()==0 ? false : content | |
| } | |
| } else { | |
| handle(line) | |
| } | |
| } | |
| abstract handle(String line) | |
| } | |
| class Section extends Entry { | |
| private Collection<Parameter> parameters = [] | |
| def getLastEntry() { | |
| return this | |
| } | |
| def handle(String line) { | |
| if(line==~IniDocumentor.PARAMETER_REGEX) { | |
| def matching = (line=~IniDocumentor.PARAMETER_REGEX) | |
| def param = new Parameter(doc:doc, name:matching[0][1], value:matching[0][2], finalComments:comments) | |
| comments = [:] | |
| parameters << param | |
| } else if(line==~IniDocumentor.SECTION_REGEX) { | |
| def matching = (line=~IniDocumentor.SECTION_REGEX) | |
| if(name==null) { | |
| // Found section name | |
| name = matching[0][1] | |
| finalComments = comments | |
| comments = [:] | |
| } else { | |
| def newSection = new Section(doc:doc, name:matching[0][1], finalComments:comments) | |
| comments = [:] | |
| doc.sections << newSection | |
| } | |
| } else { | |
| } | |
| } | |
| public String toString() { | |
| return name+"\n"+finalComments[IniDocumentor.BRIEF_COMMENT]+parameters.inject("") { text, param -> text+"\n\t"+param.toString() } | |
| } | |
| } | |
| class Parameter extends Entry { | |
| def value; | |
| def handle(String line) { | |
| throw new UnsupportedOperationException("not in parameter\n"+line) | |
| } | |
| String toString() { | |
| return name+"="+value+"\n"+finalComments | |
| } | |
| } | |
| public class IniDocumentor { | |
| public static final String DEFAULT_PATH = "../PSS.ini" | |
| public static final String DEFAULT_DOC = "##" | |
| public static final String DEFAULT_OUTPUT = "../../../../target/doc/PSS.ini.mediawiki" | |
| public static final String BRIEF_COMMENT = "@brief" | |
| public static final String MANDATORY_COMMENT = "@mandatory" | |
| public static final String OPT_COMMENT = "@optionnal" | |
| public static final String DEPRECATED_COMMENT = "@deprecated" | |
| public static final String DEFAULT_COMMENT = "@default" | |
| public static final String TYPE_COMMENT = "@type" | |
| public static final def PARAMETER_REGEX = /^(\w+)\s*=\s*((?:\p{Alnum}|\p{Punct})*)\s*(;#)*(;#)*.*/ | |
| public static final def SECTION_REGEX = /\[(\w*)\].*/ | |
| String path; | |
| String docStart; | |
| Collection<String> formattings = [BRIEF_COMMENT, MANDATORY_COMMENT, OPT_COMMENT, DEFAULT_COMMENT, TYPE_COMMENT,DEPRECATED_COMMENT] | |
| Collection<Section> sections = [] | |
| /** | |
| * Parse given file | |
| */ | |
| private void parse() throws Exception { | |
| def file = new File(path) | |
| println "parsing ..." | |
| file.eachLine() { line -> | |
| if(line.trim().size()>0) { | |
| getLastEntry().add(line) | |
| } | |
| print "." | |
| } | |
| println "\nfinished parsing \"${path}\"" | |
| } | |
| def getLastEntry() { | |
| if(sections.isEmpty()) { | |
| sections << new Section(doc:this) | |
| } | |
| def section = sections.get(sections.size()-1) | |
| return section.getLastEntry() | |
| } | |
| def toHTML(String outputPath) { | |
| File output = new File(outputPath) | |
| output.parentFile.mkdirs() | |
| FileWriter writer = new FileWriter(output) | |
| def builder = new MarkupBuilder(writer) | |
| builder.html { | |
| head { | |
| title "Documentation for ${path} built on ${new Date()}" | |
| } | |
| body { | |
| sections.each { section -> | |
| a(name:section.name) | |
| h3 section.name | |
| p section.finalComments[BRIEF_COMMENT] | |
| section.parameters.each { parameter -> | |
| a(name:parameter.name) | |
| if(parameter.finalComments.containsKey(DEPRECATED_COMMENT)) { | |
| h4 { | |
| strike parameter.name | |
| } | |
| p parameter.finalComments[DEPRECATED_COMMENT] ?: "Abandonné" | |
| } else if(parameter.finalComments.containsKey(MANDATORY_COMMENT)) { | |
| h4 { | |
| u parameter.name | |
| } | |
| p parameter.finalComments[MANDATORY_COMMENT] ?: "Obligatoire" | |
| } else { | |
| h4 parameter.name | |
| if(parameter.finalComments[OPT_COMMENT]!=false) | |
| p parameter.finalComments[OPT_COMMENT] | |
| } | |
| if(parameter.finalComments.containsKey(BRIEF_COMMENT)) { | |
| p parameter.finalComments[BRIEF_COMMENT] | |
| } | |
| if(parameter.finalComments.containsKey(TYPE_COMMENT)) { | |
| p "Type : "+parameter.finalComments[TYPE_COMMENT] | |
| } | |
| if(parameter.finalComments.containsKey(DEFAULT_COMMENT)) { | |
| p "Valeur par défaut : "+parameter.finalComments[DEFAULT_COMMENT] | |
| } | |
| p { | |
| b "Valeur du fichier : " | |
| span parameter.value | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| def toMediaWiki(String outputPath) { | |
| File output = new File(outputPath) | |
| output.parentFile.mkdirs() | |
| FileWriter writer = new FileWriter(output) | |
| writer.write("= Documentation for ${path} built on ${new Date()} =\n"); | |
| sections.each { section -> | |
| writer.write("=="+section.name+"==\n"); | |
| writer.write(section.finalComments[BRIEF_COMMENT]?:""+"\n") | |
| section.parameters.each { parameter -> | |
| writer.write("==="+parameter.name+"===\n") | |
| if(parameter.finalComments.containsKey(DEPRECATED_COMMENT)) { | |
| writer.write("'''"+(parameter.finalComments[DEPRECATED_COMMENT] ?: "Abandonné")+"'''\n\n") | |
| } else if(parameter.finalComments.containsKey(MANDATORY_COMMENT)) { | |
| writer.write("'''"+(parameter.finalComments[MANDATORY_COMMENT] ?: "Obligatoire" )+"'''\n\n") | |
| } else { | |
| if(parameter.finalComments[OPT_COMMENT]!=false) | |
| writer.write(parameter.finalComments[OPT_COMMENT]?.trim()+"\n\n") | |
| } | |
| if(parameter.finalComments.containsKey(BRIEF_COMMENT)) { | |
| writer.write(parameter.finalComments[BRIEF_COMMENT]?.trim()+"\n\n") | |
| } | |
| if(parameter.finalComments.containsKey(TYPE_COMMENT)) { | |
| writer.write("Type : "+parameter.finalComments[TYPE_COMMENT]+"\n\n") | |
| } | |
| if(parameter.finalComments.containsKey(DEFAULT_COMMENT)) { | |
| writer.write("Valeur par défaut : "+parameter.finalComments[DEFAULT_COMMENT]+"\n\n") | |
| } | |
| writer.write("'''Valeur du fichier : "+ parameter.value+"'''\n\n") | |
| } | |
| } | |
| writer.close() | |
| } | |
| def toOutput(String outputPath) { | |
| println "generating output" | |
| def lowCasePath = outputPath.toLowerCase() | |
| if(lowCasePath==~/.*\.htm.*/) | |
| toHTML(outputPath) | |
| else if(lowCasePath==~/.*\.mediawiki*/) | |
| toMediaWiki(outputPath) | |
| else | |
| throw new UnsupportedOperationException("output format of "+outputPath+" is not yet supported") | |
| println "finished generating \"${outputPath}\"" | |
| } | |
| static void main(args) throws Exception { | |
| def cli = new CliBuilder(usage:'groovy ini_doc.groovy options') | |
| cli.o(longOpt: 'output', 'Output file. Notice it will be html content, so use appropriated format. Notice output format will be either html (if path ends with .html*) or mediawiki synatx (if path ends with .mediawiki). Defaults to '+DEFAULT_OUTPUT) | |
| cli.h(longOpt: 'help', 'Shows this help') | |
| cli.p(longOpt: 'path', 'Path of PSS.ini file. Defaults to '+DEFAULT_PATH) | |
| cli.d(longOpt: 'docPrefix', 'Prefix for documentation comments. Defaults to '+DEFAULT_DOC) | |
| def opt = cli.parse(args); | |
| if(opt.h) { | |
| cli.usage(); | |
| } else { | |
| def documentor = new IniDocumentor( | |
| path: opt.p==false ? DEFAULT_PATH : opt.p, | |
| docStart: opt.d==false ? DEFAULT_DOC : opt.d | |
| ) | |
| documentor.parse() | |
| /* now output it */ | |
| documentor.toOutput(opt.o==false ? DEFAULT_OUTPUT : opt.o) | |
| } | |
| } | |
| } | |
| IniDocumentor.main(this.args) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment