-
Notifications
You must be signed in to change notification settings - Fork 0
/
groc.groovy
232 lines (223 loc) · 6.86 KB
/
groc.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/**
*## Introduction
*Inspired by [Docco](http://jashkenas.github.com/docco/), [Groc](http://fix.github.com/Groc/groc.groovy.html) is a *document generator* based on your comments in the source code.
*This is written in [Groovy](http://groovy.codehaus.org/)
*
*You can optionally use the [Markdown](http://en.wikipedia.org/wiki/Markdown) to enhance the formatting.
*
*Find the source on [Github](http://github.com/fix/Groc/).
*
*## Installation
*You need to have Groovy installed on your machine.
*
*## Use
*You can launch it inside a directory containing your groovy files using `groovy https://raw.github.com/fix/Groc/master/groc.groovy [extension]`.
*
*It will create a folder called `docs` with all your html files.
*
*Only comments starting with `/**` are parsed whereas `//` or `/*` comments are left in the code.
*/
/**
* Grab the MarkDown processor. All capabilities with extensions can be used. See [PegDown](https://github.com/sirthias/pegdown) for more information.
*/
@Grab(group='org.pegdown', module='pegdown', version='1.2.1')
/**
* Import MarkupBuilder and PegDown processor
*/
import groovy.xml.MarkupBuilder
import org.pegdown.PegDownProcessor
/**
* Using CLIBuilder to parse the arg line
*/
def cli = new CliBuilder(usage:'groovy path/to/groc.groovy')
cli.e(args:1, argName:'extension', 'optional extension, default is "groovy", supported are gradle, java and css')
cli.d(args:1, argName:'docs directory', 'optional docs folder extension, default is "docs"')
def options = cli.parse(args)
if(options){
extension=options.e?options.e:"groovy"
docs=options.d?options.d:"docs"
}
brushes=[
groovy:"shBrushGroovy.js",
gradle:"shBrushGroovy.js",
java :"shBrushJava.js",
css :"shBrushCss.js"
]
/**
* Set Initial parameters such as current folder to process your `.groovy` files
*/
root=new File(".")
docs=new File(docs)
docs.mkdir()
toc=[:]
/**
*Executing for all `.groovy` files in the folder
*/
def parseFiles(File folder,String relativePath="", String returningPath=""){
folder.listFiles().sort{
it.isDirectory()?1:-1
}.each{
if(it.name =~ ".*\\.${extension}\$"){
File docFolder=new File(docs.path+"/"+relativePath)
docFolder.mkdirs()
File docSource=new File(docFolder.path+"/"+it.name+".html")
toc[it]=[
docSource,
relativePath+it.name+".html",
returningPath,
]
}
else if(it.isDirectory()&&it.name!="docs"&&!it.name.startsWith(".")){
parseFiles(it,relativePath+it.name+"/", returningPath+"../")
}
}
}
parseFiles(root)
/**
* This comment is not parsed
* because only single star when opening the comment.
*
*
**/
/*
* Comment not parsed
*/
/*********************
*## The main method
*
*You can create this kind of text spanning all the page commenting "empty" code
********************/
/**
* Take input file and output file. Erase output if existing
*/
def createGroc(File source, File output, String returningPath){
/**
*## The Parser
*/
def parsedCode=[]
boolean commentOn=false
def currentCode=["",""] // comment,code
source.eachLine{
def line=it
if(it =~ /^ *\/\*\*.*/){
if(!commentOn){
if(currentCode && currentCode.join("").size()>0){
parsedCode<<currentCode
currentCode=["", ""]
}
line=it.replaceFirst(/^ *\/\*\*.*/,"")
commentOn=true
}
}
if(commentOn){
currentCode[0]+=((line =~ ".?\\*\\**/")
.replaceFirst("") =~ "^ *\\*")
.replaceFirst("")+"\n"
}
else{
if(line.size()==0){
if(currentCode && currentCode.join("").size()>0)parsedCode<<currentCode
currentCode=["", ""]
}
else currentCode[1]+=line+"\n"
}
if(it =~ /.*\*\//){
commentOn=false
}
}
if(currentCode && currentCode.join("").size()>0)parsedCode << currentCode
/**
* Applying PegDown.markdown to all parsed comments
*/
PegDownProcessor m=new PegDownProcessor()
parsedCode.each{
it[0] = m.markdownToHtml(it[0])
}
/**
*
*## The HTML template, thanks to MarkupBuilder
*
*/
def tl=new MarkupBuilder(new FileWriter(output)).html{
head{
title("Groc "+source.name)
meta("http-equiv":"content-type", content:"text/html; charset=UTF8")
/**
* Inlining all the javascript and css
*/
style(media:"all"){
mkp.yieldUnescaped("http://netdna.bootstrapcdn.com/bootstrap/2.3.2/css/bootstrap.min.css".toURL().text)
}
style(media:"all"){
mkp.yieldUnescaped("https://raw.github.com/fix/Groc/master/groc.css".toURL().text)
}
style(media:"all"){
mkp.yieldUnescaped("http://alexgorbatchev.com/pub/sh/current/styles/shCore.css".toURL().text)
}
script(type:"text/javascript"){
mkp.yieldUnescaped("http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js".toURL().text)
}
script(type:"text/javascript"){
mkp.yieldUnescaped("http://alexgorbatchev.com/pub/sh/current/scripts/${brushes[extension]}".toURL().text)
}
}
body{
div(id:"content"){
if(toc.size()>1){
div("class":"topbar"){
div("class":"topbar-inner"){
div("class":"container"){
a("class":"brand", href:"#"){mkp.yield(source.name)}
ul("class":"nav"){
toc.entrySet().each{item->
li("class":(item.key==source?"active":"")){
a("class":"source",
href:returningPath+item.value[1],
item.key.path.replaceFirst("./","")
)
}
}
}
}
}
}
}
if(toc.size()<2){
h1{mkp.yield(source.name)}
}
table(cellpadding:"0", cellspacing:"0"){
tbody{
parsedCode.eachWithIndex {code,i->
tr(id:"section-"+i){
td("class":"docs"+(code[1].size()>0?"":" main"), colspan:code[1].size()>0?"1":"2"){
if(code[0]!=""){
div("class":(code[1].size()>0?"bubble":"")){
div("class":"pilwrap"){
a("class":"pilcrow", href:"#section-"+i, "#")
}
mkp.yieldUnescaped(code[0])
}
}
}
if(code[1].size()>0){
td("class":"codes"){
pre("class":"brush: ${extension == "gradle" ? "groovy" : extension}; gutter: false; toolbar: false;"){
mkp.yield(code[1])
}
}
}
}
}
}
}
}
script(type:"text/javascript"){ mkp.yield("SyntaxHighlighter.all()") }
}
}
}
/**
*## Do It!
*/
toc.entrySet().each{
createGroc(it.key,it.value[0], it.value[2])
}