rokko 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +3 -0
- data/README.md +3 -0
- data/Rakefile +4 -0
- data/TODO +6 -0
- data/bin/rokko +90 -0
- data/lib/rokko/assets/docco.css +121 -0
- data/lib/rokko/assets/highlight.css +127 -0
- data/lib/rokko/assets/highlight.pack.js +1 -0
- data/lib/rokko/index_layout.mustache +42 -0
- data/lib/rokko/index_layout.rb +39 -0
- data/lib/rokko/layout.mustache +51 -0
- data/lib/rokko/layout.rb +63 -0
- data/lib/rokko/task.rb +56 -0
- data/lib/rokko/version.rb +3 -0
- data/lib/rokko.rb +127 -0
- data/rokko.gemspec +24 -0
- metadata +111 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
data/TODO
ADDED
data/bin/rokko
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#/ Usage: rokko [-i [INDEX_FILE]][-o <dir>] <file>...
|
4
|
+
#/ Generate literate-programming-style documentation for Ruby source <file>s.
|
5
|
+
#/
|
6
|
+
#/ Options:
|
7
|
+
#/ -i, --index=<file> Also generate an index with links to HTML files or use <file> as
|
8
|
+
#/ index
|
9
|
+
#/ -o, --output=<dir> Directory where generated HTML files are written
|
10
|
+
#/ --help Show this help message
|
11
|
+
|
12
|
+
require 'optparse'
|
13
|
+
require 'fileutils'
|
14
|
+
begin
|
15
|
+
$:.unshift(File.expand_path('../../lib', __FILE__).sub(/^#{Dir.pwd}\//, ''))
|
16
|
+
require 'rokko'
|
17
|
+
rescue LoadError
|
18
|
+
if !defined?(Gem)
|
19
|
+
require 'rubygems'
|
20
|
+
retry
|
21
|
+
end
|
22
|
+
raise
|
23
|
+
end
|
24
|
+
|
25
|
+
# Write usage message to stdout and exit
|
26
|
+
def usage(stream=$stderr, status=1)
|
27
|
+
stream.puts File.readlines(__FILE__).
|
28
|
+
grep(/^#\//).
|
29
|
+
map {|line| line.sub(/^#. ?/, '')}.
|
30
|
+
join
|
31
|
+
exit status
|
32
|
+
end
|
33
|
+
|
34
|
+
# Like `Kernel#abort` but writes a note encouraging the user to consult.
|
35
|
+
# `rokko --help` for more information
|
36
|
+
def abort_with_note(message=nil)
|
37
|
+
$stderr.puts message if message
|
38
|
+
abort "See `rokko --help' for usage information."
|
39
|
+
end
|
40
|
+
|
41
|
+
# Parse command line options, aborting if anything goes wrong.
|
42
|
+
output_dir = '.'
|
43
|
+
sources = []
|
44
|
+
options = {}
|
45
|
+
ARGV.options { |o|
|
46
|
+
o.program_name = File.basename($0)
|
47
|
+
o.on("-o", "--output=DIR") {|dir| output_dir = dir}
|
48
|
+
o.on("-i", "--index [FILE]") {|index| index ? options[:index] = index : options[:generate_index] = true}
|
49
|
+
o.on_tail("-h", "--help") {usage($stdout, 0)}
|
50
|
+
o.parse!
|
51
|
+
} or abort_with_note
|
52
|
+
|
53
|
+
# Eat sources from ARGV.
|
54
|
+
sources << ARGV.shift while ARGV.any?
|
55
|
+
|
56
|
+
# Make sure we have some files to work with.
|
57
|
+
if sources.empty?
|
58
|
+
abort_with_note "#{File.basename($0)}: no input <file>s given"
|
59
|
+
end
|
60
|
+
|
61
|
+
# Find README file for `index.html` and delete it from `sources`
|
62
|
+
if options[:generate_index]
|
63
|
+
readme_source = sources.detect {|f| File.basename(f) =~ /README(\.(md|text|markdown|mdown|mkd|mkdn)$)?/i}
|
64
|
+
readme = readme_source ? File.read(sources.delete(readme_source)) : ''
|
65
|
+
end
|
66
|
+
|
67
|
+
# Run each file through Rokko and write output.
|
68
|
+
sources.each do |filename|
|
69
|
+
rokko = Rokko::Rokko.new(filename, sources, options)
|
70
|
+
dest = File.join(output_dir, filename.sub(Regexp.new("#{File.extname(filename)}$"), ".html"))
|
71
|
+
puts "rokko: #{filename} -> #{dest}"
|
72
|
+
FileUtils.mkdir_p File.dirname(dest)
|
73
|
+
File.open(dest, 'wb') {|fd| fd.write(rokko.to_html)}
|
74
|
+
end
|
75
|
+
|
76
|
+
# Generate index.html if needed.
|
77
|
+
if options[:generate_index]
|
78
|
+
require 'rokko/index_layout'
|
79
|
+
dest = File.join(output_dir, 'index.html')
|
80
|
+
puts "rokko: #{dest}"
|
81
|
+
File.open(dest, 'wb') {|fd| fd.write(Rokko::IndexLayout.new(sources, readme).render)}
|
82
|
+
end
|
83
|
+
|
84
|
+
# Generate and use specified file as index.
|
85
|
+
if options[:index] && source_index = sources.delete(options[:index])
|
86
|
+
rokko = Rokko::Rokko.new(source_index, sources, options.merge(:preserve_urls => true))
|
87
|
+
dest = File.join(output_dir, 'index.html')
|
88
|
+
puts "rokko: #{source_index} -> index.html"
|
89
|
+
File.open(dest, 'wb') {|fd| fd.write(rokko.to_html)}
|
90
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
/*--------------------- Layout and Typography ----------------------------*/
|
2
|
+
body {
|
3
|
+
font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
|
4
|
+
font-size: 15px;
|
5
|
+
line-height: 22px;
|
6
|
+
color: #252519;
|
7
|
+
margin: 0; padding: 0;
|
8
|
+
text-align: left;
|
9
|
+
}
|
10
|
+
a {
|
11
|
+
color: #261a3b;
|
12
|
+
}
|
13
|
+
a:visited {
|
14
|
+
color: #261a3b;
|
15
|
+
}
|
16
|
+
p {
|
17
|
+
margin: 0 0 15px 0;
|
18
|
+
}
|
19
|
+
h1, h2, h3, h4, h5, h6 {
|
20
|
+
margin: 0px 0 15px 0;
|
21
|
+
}
|
22
|
+
h1 {
|
23
|
+
margin-top: 40px;
|
24
|
+
}
|
25
|
+
#container {
|
26
|
+
position: relative;
|
27
|
+
}
|
28
|
+
#background {
|
29
|
+
position: fixed;
|
30
|
+
top: 0; left: 525px; right: 0; bottom: 0;
|
31
|
+
background: #f5f5ff;
|
32
|
+
border-left: 1px solid #e5e5ee;
|
33
|
+
z-index: -1;
|
34
|
+
}
|
35
|
+
#jump_to, #jump_page {
|
36
|
+
background: white;
|
37
|
+
-webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
|
38
|
+
-webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
|
39
|
+
font: 10px Arial;
|
40
|
+
text-transform: uppercase;
|
41
|
+
cursor: pointer;
|
42
|
+
text-align: right;
|
43
|
+
}
|
44
|
+
#jump_to, #jump_wrapper {
|
45
|
+
position: fixed;
|
46
|
+
right: 0; top: 0;
|
47
|
+
padding: 5px 10px;
|
48
|
+
}
|
49
|
+
#jump_wrapper {
|
50
|
+
padding: 0;
|
51
|
+
display: none;
|
52
|
+
}
|
53
|
+
#jump_to:hover #jump_wrapper {
|
54
|
+
display: block;
|
55
|
+
}
|
56
|
+
#jump_page {
|
57
|
+
padding: 5px 0 3px;
|
58
|
+
margin: 0 0 25px 25px;
|
59
|
+
}
|
60
|
+
#jump_page .source {
|
61
|
+
display: block;
|
62
|
+
padding: 5px 10px;
|
63
|
+
text-decoration: none;
|
64
|
+
border-top: 1px solid #eee;
|
65
|
+
}
|
66
|
+
#jump_page .source:hover {
|
67
|
+
background: #f5f5ff;
|
68
|
+
}
|
69
|
+
#jump_page .source:first-child {
|
70
|
+
}
|
71
|
+
table td {
|
72
|
+
border: 0;
|
73
|
+
outline: 0;
|
74
|
+
}
|
75
|
+
td.docs, th.docs {
|
76
|
+
max-width: 450px;
|
77
|
+
min-width: 450px;
|
78
|
+
min-height: 5px;
|
79
|
+
padding: 10px 25px 1px 50px;
|
80
|
+
overflow-x: hidden;
|
81
|
+
vertical-align: top;
|
82
|
+
text-align: left;
|
83
|
+
}
|
84
|
+
.docs pre {
|
85
|
+
margin: 15px 0 15px;
|
86
|
+
padding-left: 15px;
|
87
|
+
}
|
88
|
+
.docs p tt, .docs p code {
|
89
|
+
background: #f8f8ff;
|
90
|
+
border: 1px solid #dedede;
|
91
|
+
font-size: 12px;
|
92
|
+
padding: 0 0.2em;
|
93
|
+
}
|
94
|
+
.pilwrap {
|
95
|
+
position: relative;
|
96
|
+
}
|
97
|
+
.pilcrow {
|
98
|
+
font: 12px Arial;
|
99
|
+
text-decoration: none;
|
100
|
+
color: #454545;
|
101
|
+
position: absolute;
|
102
|
+
top: 3px; left: -20px;
|
103
|
+
padding: 1px 2px;
|
104
|
+
opacity: 0;
|
105
|
+
-webkit-transition: opacity 0.2s linear;
|
106
|
+
}
|
107
|
+
td.docs:hover .pilcrow {
|
108
|
+
opacity: 1;
|
109
|
+
}
|
110
|
+
td.code, th.code {
|
111
|
+
padding: 14px 15px 16px 25px;
|
112
|
+
width: 100%;
|
113
|
+
vertical-align: top;
|
114
|
+
background: #f5f5ff;
|
115
|
+
border-left: 1px solid #e5e5ee;
|
116
|
+
}
|
117
|
+
pre, tt, code {
|
118
|
+
font-size: 12px; line-height: 18px;
|
119
|
+
font-family: Monaco, Consolas, "Lucida Console", monospace;
|
120
|
+
margin: 0; padding: 0;
|
121
|
+
}
|
@@ -0,0 +1,127 @@
|
|
1
|
+
/*
|
2
|
+
|
3
|
+
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
4
|
+
|
5
|
+
*/
|
6
|
+
|
7
|
+
pre code {
|
8
|
+
display: block;
|
9
|
+
color: #000
|
10
|
+
}
|
11
|
+
|
12
|
+
pre .comment,
|
13
|
+
pre .template_comment,
|
14
|
+
pre .diff .header,
|
15
|
+
pre .javadoc {
|
16
|
+
color: #998;
|
17
|
+
font-style: italic
|
18
|
+
}
|
19
|
+
|
20
|
+
pre .keyword,
|
21
|
+
pre .css .rule .keyword,
|
22
|
+
pre .winutils,
|
23
|
+
pre .javascript .title,
|
24
|
+
pre .lisp .title,
|
25
|
+
pre .subst {
|
26
|
+
color: #000;
|
27
|
+
font-weight: bold
|
28
|
+
}
|
29
|
+
|
30
|
+
pre .number,
|
31
|
+
pre .hexcolor {
|
32
|
+
color: #40a070
|
33
|
+
}
|
34
|
+
|
35
|
+
pre .string,
|
36
|
+
pre .tag .value,
|
37
|
+
pre .phpdoc,
|
38
|
+
pre .tex .formula {
|
39
|
+
color: #d14
|
40
|
+
}
|
41
|
+
|
42
|
+
pre .title,
|
43
|
+
pre .id {
|
44
|
+
color: #900;
|
45
|
+
font-weight: bold
|
46
|
+
}
|
47
|
+
|
48
|
+
pre .javascript .title,
|
49
|
+
pre .lisp .title,
|
50
|
+
pre .subst {
|
51
|
+
font-weight: normal
|
52
|
+
}
|
53
|
+
|
54
|
+
pre .class .title,
|
55
|
+
pre .tex .command {
|
56
|
+
color: #458;
|
57
|
+
font-weight: bold
|
58
|
+
}
|
59
|
+
|
60
|
+
pre .tag,
|
61
|
+
pre .css .keyword,
|
62
|
+
pre .html .keyword,
|
63
|
+
pre .tag .title,
|
64
|
+
pre .django .tag .keyword {
|
65
|
+
color: #000080;
|
66
|
+
font-weight: normal
|
67
|
+
}
|
68
|
+
|
69
|
+
pre .attribute,
|
70
|
+
pre .variable,
|
71
|
+
pre .instancevar,
|
72
|
+
pre .lisp .body {
|
73
|
+
color: #008080
|
74
|
+
}
|
75
|
+
|
76
|
+
pre .regexp {
|
77
|
+
color: #009926
|
78
|
+
}
|
79
|
+
|
80
|
+
pre .class {
|
81
|
+
color: #458;
|
82
|
+
font-weight: bold
|
83
|
+
}
|
84
|
+
|
85
|
+
pre .symbol,
|
86
|
+
pre .ruby .symbol .string,
|
87
|
+
pre .ruby .symbol .keyword,
|
88
|
+
pre .ruby .symbol .keymethods,
|
89
|
+
pre .lisp .keyword,
|
90
|
+
pre .tex .special {
|
91
|
+
color: #990073
|
92
|
+
}
|
93
|
+
|
94
|
+
pre .builtin,
|
95
|
+
pre .built_in,
|
96
|
+
pre .lisp .title {
|
97
|
+
color: #0086b3
|
98
|
+
}
|
99
|
+
|
100
|
+
pre .preprocessor,
|
101
|
+
pre .pi,
|
102
|
+
pre .doctype,
|
103
|
+
pre .shebang,
|
104
|
+
pre .cdata {
|
105
|
+
color: #999;
|
106
|
+
font-weight: bold
|
107
|
+
}
|
108
|
+
|
109
|
+
pre .deletion {
|
110
|
+
background: #fdd
|
111
|
+
}
|
112
|
+
|
113
|
+
pre .addition {
|
114
|
+
background: #dfd
|
115
|
+
}
|
116
|
+
|
117
|
+
pre .diff .change {
|
118
|
+
background: #0086b3
|
119
|
+
}
|
120
|
+
|
121
|
+
pre .chunk {
|
122
|
+
color: #aaa
|
123
|
+
}
|
124
|
+
|
125
|
+
pre .tex .formula {
|
126
|
+
opacity: 0.5;
|
127
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
var hljs=new function(){var p={};var a={};function n(c){return c.replace(/&/gm,"&").replace(/</gm,"<").replace(/>/gm,">")}function k(s,r){if(!s){return false}for(var c=0;c<s.length;c++){if(s[c]==r){return true}}return false}function e(s,r,c){var t="m"+(s.cI?"i":"")+(c?"g":"");return new RegExp(r,t)}function j(r){for(var c=0;c<r.childNodes.length;c++){node=r.childNodes[c];if(node.nodeName=="CODE"){return node}if(!(node.nodeType==3&&node.nodeValue.match(/\s+/))){return null}}}function h(u,t){var s="";for(var r=0;r<u.childNodes.length;r++){if(u.childNodes[r].nodeType==3){var c=u.childNodes[r].nodeValue;if(t){c=c.replace(/\n/g,"")}s+=c}else{if(u.childNodes[r].nodeName=="BR"){s+="\n"}else{s+=h(u.childNodes[r])}}}s=s.replace(/\r/g,"\n");return s}function b(t){var r=t.className.split(/\s+/);r=r.concat(t.parentNode.className.split(/\s+/));for(var c=0;c<r.length;c++){var s=r[c].replace(/^language-/,"");if(p[s]||s=="no-highlight"){return s}}}function d(c){var r=[];(function(t,u){for(var s=0;s<t.childNodes.length;s++){if(t.childNodes[s].nodeType==3){u+=t.childNodes[s].nodeValue.length}else{if(t.childNodes[s].nodeName=="BR"){u+=1}else{r.push({event:"start",offset:u,node:t.childNodes[s]});u=arguments.callee(t.childNodes[s],u);r.push({event:"stop",offset:u,node:t.childNodes[s]})}}}return u})(c,0);return r}function m(z,A,y){var s=0;var x="";var u=[];function v(){if(z.length&&A.length){if(z[0].offset!=A[0].offset){return(z[0].offset<A[0].offset)?z:A}else{return(z[0].event=="start"&&A[0].event=="stop")?A:z}}else{return z.length?z:A}}function t(E){var F="<"+E.nodeName.toLowerCase();for(var C=0;C<E.attributes.length;C++){var D=E.attributes[C];F+=" "+D.nodeName.toLowerCase();if(D.nodeValue!=undefined){F+='="'+n(D.nodeValue)+'"'}}return F+">"}function B(C){return"</"+C.nodeName.toLowerCase()+">"}while(z.length||A.length){var w=v().splice(0,1)[0];x+=n(y.substr(s,w.offset-s));s=w.offset;if(w.event=="start"){x+=t(w.node);u.push(w.node)}else{if(w.event=="stop"){var r=u.length;do{r--;var c=u[r];x+=B(c)}while(c!=w.node);u.splice(r,1);while(r<u.length){x+=t(u[r]);r++}}}}x+=y.substr(s);return x}function g(K,E){function A(r,N){for(var M=0;M<N.sm.length;M++){if(N.sm[M].bR.test(r)){return N.sm[M]}}return null}function x(M,r){if(D[M].e&&D[M].eR.test(r)){return 1}if(D[M].eW){var N=x(M-1,r);return N?N+1:0}return 0}function y(r,M){return M.iR&&M.iR.test(r)}function B(P,O){var N=[];for(var M=0;M<P.sm.length;M++){N.push(P.sm[M].b)}var r=D.length-1;do{if(D[r].e){N.push(D[r].e)}r--}while(D[r+1].eW);if(P.i){N.push(P.i)}return e(O,"("+N.join("|")+")",true)}function t(N,M){var O=D[D.length-1];if(!O.t){O.t=B(O,I)}O.t.lastIndex=M;var r=O.t.exec(N);if(r){return[N.substr(M,r.index-M),r[0],false]}else{return[N.substr(M),"",true]}}function c(P,r){var M=I.cI?r[0].toLowerCase():r[0];for(var O in P.keywordGroups){if(!P.keywordGroups.hasOwnProperty(O)){continue}var N=P.keywordGroups[O].hasOwnProperty(M);if(N){return[O,N]}}return false}function G(N,Q){if(!Q.k||!Q.l){return n(N)}if(!Q.lR){var P="("+Q.l.join("|")+")";Q.lR=e(I,P,true)}var O="";var R=0;Q.lR.lastIndex=0;var M=Q.lR.exec(N);while(M){O+=n(N.substr(R,M.index-R));var r=c(Q,M);if(r){u+=r[1];O+='<span class="'+r[0]+'">'+n(M[0])+"</span>"}else{O+=n(M[0])}R=Q.lR.lastIndex;M=Q.lR.exec(N)}O+=n(N.substr(R,N.length-R));return O}function L(r,N){if(N.subLanguage&&a[N.subLanguage]){var M=g(N.subLanguage,r);u+=M.keyword_count;C+=M.r;return M.value}else{return G(r,N)}}function J(N,r){var M=N.nM?"":'<span class="'+N.displayClassName+'">';if(N.rB){s+=M;N.buffer=""}else{if(N.eB){s+=n(r)+M;N.buffer=""}else{s+=M;N.buffer=r}}D[D.length]=N}function F(M,O,R){var P=D[D.length-1];if(R){s+=L(P.buffer+M,P);return false}var S=A(O,P);if(S){s+=L(P.buffer+M,P);J(S,O);C+=S.r;return S.rB}var r=x(D.length-1,O);if(r){var T=P.nM?"":"</span>";if(P.rE){s+=L(P.buffer+M,P)+T}else{if(P.eE){s+=L(P.buffer+M,P)+T+n(O)}else{s+=L(P.buffer+M+O,P)+T}}while(r>1){T=D[D.length-2].nM?"":"</span>";s+=T;r--;D.length--}var Q=D[D.length-1];D.length--;D[D.length-1].buffer="";if(Q.starts){for(var N=0;N<I.m.length;N++){if(I.m[N].cN==Q.starts){J(I.m[N],"");break}}}return P.rE}if(y(O,P)){throw"Illegal"}}var I=p[K];var D=[I.dM];var C=0;var u=0;var s="";try{var w=0;I.dM.buffer="";do{var z=t(E,w);var v=F(z[0],z[1],z[2]);w+=z[0].length;if(!v){w+=z[1].length}}while(!z[2]);if(D.length>1){throw"Illegal"}return{language:K,r:C,keyword_count:u,value:s}}catch(H){if(H=="Illegal"){return{language:null,r:0,keyword_count:0,value:n(E)}}else{throw H}}}function i(){function r(y,x){if(y.compiled){return}if(y.b){y.bR=e(x,"^"+y.b)}if(y.e){y.eR=e(x,"^"+y.e)}if(y.i){y.iR=e(x,"^(?:"+y.i+")")}if(y.r==undefined){y.r=1}if(!y.displayClassName){y.displayClassName=y.cN}if(!y.cN){y.nM=true}for(var w in y.k){if(!y.k.hasOwnProperty(w)){continue}if(y.k[w] instanceof Object){y.keywordGroups=y.k}else{y.keywordGroups={keyword:y.k}}break}y.sm=[];if(y.c){for(var v=0;v<y.c.length;v++){if(y.c[v] instanceof Object){y.sm.push(y.c[v])}else{for(var u=0;u<x.m.length;u++){if(x.m[u].cN==y.c[v]){y.sm.push(x.m[u])}}}}}y.compiled=true;for(var v=0;v<y.sm.length;v++){r(y.sm[v],x)}}for(var t in p){if(!p.hasOwnProperty(t)){continue}var c=[p[t].dM].concat(p[t].m);for(var s=0;s<c.length;s++){r(c[s],p[t])}}}function f(){if(f.called){return}f.called=true;i();a=p}function q(v,A,r){f();var C=h(v,r);var t=b(v);if(t=="no-highlight"){return}if(t){var y=g(t,C)}else{var y={language:"",keyword_count:0,r:0,value:n(C)};var z=y;for(var B in a){if(!a.hasOwnProperty(B)){continue}var w=g(B,C);if(w.keyword_count+w.r>z.keyword_count+z.r){z=w}if(w.keyword_count+w.r>y.keyword_count+y.r){z=y;y=w}}}var u=v.className;if(!u.match(y.language)){u=u?(u+" "+y.language):y.language}var c=d(v);if(c.length){var s=document.createElement("pre");s.innerHTML=y.value;y.value=m(c,d(s),C)}if(A){y.value=y.value.replace(/^((<[^>]+>|\t)+)/gm,function(D,G,F,E){return G.replace(/\t/g,A)})}if(r){y.value=y.value.replace(/\n/g,"<br>")}if(/MSIE [678]/.test(navigator.userAgent)&&v.tagName=="CODE"&&v.parentNode.tagName=="PRE"){var s=v.parentNode;var x=document.createElement("div");x.innerHTML="<pre><code>"+y.value+"</code></pre>";v=x.firstChild.firstChild;x.firstChild.cN=s.cN;s.parentNode.replaceChild(x.firstChild,s)}else{v.innerHTML=y.value}v.className=u;v.dataset={};v.dataset.result={language:y.language,kw:y.keyword_count,re:y.r};if(z&&z.language){v.dataset.second_best={language:z.language,kw:z.keyword_count,re:z.r}}}function l(){if(l.called){return}l.called=true;f();if(arguments.length){for(var c=0;c<arguments.length;c++){if(p[arguments[c]]){a[arguments[c]]=p[arguments[c]]}}}var s=document.getElementsByTagName("pre");for(var c=0;c<s.length;c++){var r=j(s[c]);if(r){q(r,hljs.tabReplace)}}}function o(){var c=arguments;var r=function(){l.apply(null,c)};if(window.addEventListener){window.addEventListener("DOMContentLoaded",r,false);window.addEventListener("load",r,false)}else{if(window.attachEvent){window.attachEvent("onload",r)}else{window.onload=r}}}this.LANGUAGES=p;this.initHighlightingOnLoad=o;this.highlightBlock=q;this.initHighlighting=l;this.IMR="\\b|\\B";this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="\\b(0x[A-Za-z0-9]+|\\d+(\\.\\d+)?)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:["escape"],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:["escape"],r:0};this.BE={cN:"escape",b:"\\\\.",e:this.IMR,nM:true,r:0};this.CLCM={cN:"comment",b:"//",e:"$",r:0};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NUMBER_MODE={cN:"number",b:this.NR,e:this.IMR,r:0};this.CNM={cN:"number",b:this.CNR,e:this.IMR,r:0};this.inherit=function(c,t){var s={};for(var r in c){s[r]=c[r]}if(t){for(var r in t){s[r]=t[r]}}return s}}();var initHighlightingOnLoad=hljs.initHighlightingOnLoad;hljs.LANGUAGES.ruby=function(){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var c="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var b=["comment","string","char","class","function","constant","symbol","number","variable","identifier","regexp_container"];var d={keyword:{and:1,"false":1,then:1,defined:1,module:1,"in":1,"return":1,redo:1,"if":1,BEGIN:1,retry:1,end:1,"for":1,"true":1,self:1,when:1,next:1,until:1,"do":1,begin:1,unless:1,END:1,rescue:1,nil:1,"else":1,"break":1,undef:1,not:1,"super":1,"class":1,"case":1,require:1,yield:1,alias:1,"while":1,ensure:1,elsif:1,or:1,def:1},keymethods:{__id__:1,__send__:1,abort:1,abs:1,"all?":1,allocate:1,ancestors:1,"any?":1,arity:1,assoc:1,at:1,at_exit:1,autoload:1,"autoload?":1,"between?":1,binding:1,binmode:1,"block_given?":1,call:1,callcc:1,caller:1,capitalize:1,"capitalize!":1,casecmp:1,"catch":1,ceil:1,center:1,chomp:1,"chomp!":1,chop:1,"chop!":1,chr:1,"class":1,class_eval:1,"class_variable_defined?":1,class_variables:1,clear:1,clone:1,close:1,close_read:1,close_write:1,"closed?":1,coerce:1,collect:1,"collect!":1,compact:1,"compact!":1,concat:1,"const_defined?":1,const_get:1,const_missing:1,const_set:1,constants:1,count:1,crypt:1,"default":1,default_proc:1,"delete":1,"delete!":1,delete_at:1,delete_if:1,detect:1,display:1,div:1,divmod:1,downcase:1,"downcase!":1,downto:1,dump:1,dup:1,each:1,each_byte:1,each_index:1,each_key:1,each_line:1,each_pair:1,each_value:1,each_with_index:1,"empty?":1,entries:1,eof:1,"eof?":1,"eql?":1,"equal?":1,"eval":1,exec:1,exit:1,"exit!":1,extend:1,fail:1,fcntl:1,fetch:1,fileno:1,fill:1,find:1,find_all:1,first:1,flatten:1,"flatten!":1,floor:1,flush:1,for_fd:1,foreach:1,fork:1,format:1,freeze:1,"frozen?":1,fsync:1,getc:1,gets:1,global_variables:1,grep:1,gsub:1,"gsub!":1,"has_key?":1,"has_value?":1,hash:1,hex:1,id:1,include:1,"include?":1,included_modules:1,index:1,indexes:1,indices:1,induced_from:1,inject:1,insert:1,inspect:1,instance_eval:1,instance_method:1,instance_methods:1,"instance_of?":1,"instance_variable_defined?":1,instance_variable_get:1,instance_variable_set:1,instance_variables:1,"integer?":1,intern:1,invert:1,ioctl:1,"is_a?":1,isatty:1,"iterator?":1,join:1,"key?":1,keys:1,"kind_of?":1,lambda:1,last:1,length:1,lineno:1,ljust:1,load:1,local_variables:1,loop:1,lstrip:1,"lstrip!":1,map:1,"map!":1,match:1,max:1,"member?":1,merge:1,"merge!":1,method:1,"method_defined?":1,method_missing:1,methods:1,min:1,module_eval:1,modulo:1,name:1,nesting:1,"new":1,next:1,"next!":1,"nil?":1,nitems:1,"nonzero?":1,object_id:1,oct:1,open:1,pack:1,partition:1,pid:1,pipe:1,pop:1,popen:1,pos:1,prec:1,prec_f:1,prec_i:1,print:1,printf:1,private_class_method:1,private_instance_methods:1,"private_method_defined?":1,private_methods:1,proc:1,protected_instance_methods:1,"protected_method_defined?":1,protected_methods:1,public_class_method:1,public_instance_methods:1,"public_method_defined?":1,public_methods:1,push:1,putc:1,puts:1,quo:1,raise:1,rand:1,rassoc:1,read:1,read_nonblock:1,readchar:1,readline:1,readlines:1,readpartial:1,rehash:1,reject:1,"reject!":1,remainder:1,reopen:1,replace:1,require:1,"respond_to?":1,reverse:1,"reverse!":1,reverse_each:1,rewind:1,rindex:1,rjust:1,round:1,rstrip:1,"rstrip!":1,scan:1,seek:1,select:1,send:1,set_trace_func:1,shift:1,singleton_method_added:1,singleton_methods:1,size:1,sleep:1,slice:1,"slice!":1,sort:1,"sort!":1,sort_by:1,split:1,sprintf:1,squeeze:1,"squeeze!":1,srand:1,stat:1,step:1,store:1,strip:1,"strip!":1,sub:1,"sub!":1,succ:1,"succ!":1,sum:1,superclass:1,swapcase:1,"swapcase!":1,sync:1,syscall:1,sysopen:1,sysread:1,sysseek:1,system:1,syswrite:1,taint:1,"tainted?":1,tell:1,test:1,"throw":1,times:1,to_a:1,to_ary:1,to_f:1,to_hash:1,to_i:1,to_int:1,to_io:1,to_proc:1,to_s:1,to_str:1,to_sym:1,tr:1,"tr!":1,tr_s:1,"tr_s!":1,trace_var:1,transpose:1,trap:1,truncate:1,"tty?":1,type:1,ungetc:1,uniq:1,"uniq!":1,unpack:1,unshift:1,untaint:1,untrace_var:1,upcase:1,"upcase!":1,update:1,upto:1,"value?":1,values:1,values_at:1,warn:1,write:1,write_nonblock:1,"zero?":1,zip:1}};return{dM:{l:[a],c:b,k:d},m:[{cN:"comment",b:"#",e:"$",c:["yardoctag"]},{cN:"comment",b:"^\\=begin",e:"^\\=end",c:["yardoctag"],r:10},{cN:"comment",b:"^__END__",e:"\\n$"},{cN:"yardoctag",b:"@[A-Za-z]+",e:hljs.IMR},{cN:"function",b:"\\bdef\\s+",e:" |$|;",l:[a],k:d,c:[{cN:"ftitle",displayClassName:"title",b:c,e:hljs.IMR,l:[a],k:d},{cN:"params",b:"\\(",e:"\\)",l:[a],k:d,c:b},"comment"]},{cN:"class",b:"\\b(class|module)\\b",e:"$|;",l:[hljs.UIR],k:d,c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",e:hljs.IMR,r:0},{cN:"inheritance",b:"<\\s*",e:hljs.IMR,c:[{cN:"parent",b:"("+hljs.IR+"::)?"+hljs.IR,e:hljs.IMR}]},"comment"],k:{"class":1,module:1}},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",e:hljs.IMR,r:0},{cN:"number",b:"\\?\\w",e:hljs.IMR},{cN:"string",b:"'",e:"'",c:["escape","subst"],r:0},{cN:"string",b:'"',e:'"',c:["escape","subst"],r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?{",e:"}",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?<",e:">",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?/",e:"/",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?%",e:"%",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?-",e:"-",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:["escape","subst"],r:10},{cN:"constant",b:"(::)?([A-Z]\\w*(::)?)+",e:hljs.IMR,r:0},{cN:"symbol",b:":",e:hljs.IMR,c:["string","identifier"]},{cN:"identifier",b:a,e:hljs.IMR,l:[a],k:d,r:0},hljs.BE,{cN:"subst",b:"#\\{",e:"}",l:[a],k:d,c:b},{cN:"regexp_container",b:"("+hljs.RSR+")\\s*",e:hljs.IMR,nM:true,c:["comment","regexp"],r:0},{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:["escape"]},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))",e:hljs.IMR}]}}();
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
5
|
+
<title>{{ title }}</title>
|
6
|
+
<style type="text/css" media="screen, projection">
|
7
|
+
{{ styles }}
|
8
|
+
</style>
|
9
|
+
<script>{{{ highlight_js }}}</script>
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<div id="container">
|
13
|
+
<div id="background"></div>
|
14
|
+
<table cellspacing="0" cellpadding="0">
|
15
|
+
<tbody>
|
16
|
+
<tr>
|
17
|
+
<th class="docs">
|
18
|
+
{{#readme?}}
|
19
|
+
{{{ readme }}}
|
20
|
+
{{/readme?}}
|
21
|
+
</th>
|
22
|
+
<th class="code">
|
23
|
+
<h1>{{ title }}</h1>
|
24
|
+
<ul class="toc">
|
25
|
+
{{#dirs}}
|
26
|
+
<li>
|
27
|
+
{{ dir }}
|
28
|
+
<ul>
|
29
|
+
{{#files}}
|
30
|
+
<li><a href="{{ url }}">{{ basename }}</a></li>
|
31
|
+
{{/files}}
|
32
|
+
</ul>
|
33
|
+
</li>
|
34
|
+
{{/dirs}}
|
35
|
+
</ul>
|
36
|
+
</th>
|
37
|
+
</tr>
|
38
|
+
</tbody>
|
39
|
+
</table>
|
40
|
+
</div>
|
41
|
+
</body>
|
42
|
+
</html>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Rokko::IndexLayout < Rokko::Layout
|
2
|
+
self.template_path = File.dirname(__FILE__)
|
3
|
+
|
4
|
+
def initialize(sources, readme = '')
|
5
|
+
@sources = sources
|
6
|
+
@readme = readme
|
7
|
+
end
|
8
|
+
|
9
|
+
def title
|
10
|
+
"Table of Contents"
|
11
|
+
end
|
12
|
+
|
13
|
+
def readme
|
14
|
+
Markdown.new(@readme, :smart).to_html
|
15
|
+
end
|
16
|
+
|
17
|
+
def readme?
|
18
|
+
@readme != ""
|
19
|
+
end
|
20
|
+
|
21
|
+
def sources
|
22
|
+
@sources.sort.map do |source|
|
23
|
+
{
|
24
|
+
:path => source,
|
25
|
+
:basename => File.basename(source),
|
26
|
+
:url => source.sub(Regexp.new("#{File.extname(source)}$"), ".html")
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Groupped sources by dirname
|
32
|
+
def dirs
|
33
|
+
sources.inject(Hash.new{|hsh, key| hsh[key] = []}) do |c, source|
|
34
|
+
c[File.dirname(source[:path])].push(source)
|
35
|
+
c
|
36
|
+
end.sort.collect {|k, v| {:dir => k, :files => v}}
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
5
|
+
<title>{{ title }}</title>
|
6
|
+
<style type="text/css" media="screen, projection">
|
7
|
+
{{ styles }}
|
8
|
+
</style>
|
9
|
+
<script>{{{ highlight_js }}}</script>
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<div id="container">
|
13
|
+
<div id="background"></div>
|
14
|
+
{{#sources?}}
|
15
|
+
<div id="jump_to">
|
16
|
+
Jump To …
|
17
|
+
<div id="jump_wrapper">
|
18
|
+
<div id="jump_page">
|
19
|
+
{{#sources}}
|
20
|
+
<a class="source" href="{{ url }}">{{ basename }}</a>
|
21
|
+
{{/sources}}
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
{{/sources?}}
|
26
|
+
<table cellspacing="0" cellpadding="0">
|
27
|
+
<thead>
|
28
|
+
<tr>
|
29
|
+
<th class="docs"><h1>{{ title }}</h1></th>
|
30
|
+
<th class="code"></th>
|
31
|
+
</tr>
|
32
|
+
</thead>
|
33
|
+
<tbody>
|
34
|
+
{{#sections}}
|
35
|
+
<tr id="section-{{ num }}">
|
36
|
+
<td class="docs">
|
37
|
+
<div class="pilwrap">
|
38
|
+
<a class="pilcrow" href="#section-{{ num }}">¶</a>
|
39
|
+
</div>
|
40
|
+
{{{ docs }}}
|
41
|
+
</td>
|
42
|
+
<td class="code">
|
43
|
+
<pre class="ruby"><code>{{ code }}</code></pre>
|
44
|
+
</td>
|
45
|
+
</tr>
|
46
|
+
{{/sections}}
|
47
|
+
</tbody>
|
48
|
+
</table>
|
49
|
+
</div>
|
50
|
+
</body>
|
51
|
+
</html>
|
data/lib/rokko/layout.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
module Rokko
|
3
|
+
class Layout < Mustache
|
4
|
+
self.template_path = File.dirname(__FILE__)
|
5
|
+
|
6
|
+
def initialize(doc)
|
7
|
+
@doc = doc
|
8
|
+
end
|
9
|
+
|
10
|
+
def title
|
11
|
+
File.basename(@doc.file)
|
12
|
+
end
|
13
|
+
|
14
|
+
def styles
|
15
|
+
docco = File.read(File.join(File.dirname(__FILE__), 'assets', 'docco.css'))
|
16
|
+
highlight = File.read(File.join(File.dirname(__FILE__), 'assets', 'highlight.css'))
|
17
|
+
|
18
|
+
docco + "\n" + highlight
|
19
|
+
end
|
20
|
+
|
21
|
+
def highlight_js
|
22
|
+
js = File.read(File.join(File.dirname(__FILE__), 'assets', 'highlight.pack.js'))
|
23
|
+
|
24
|
+
js + "\nhljs.initHighlightingOnLoad();\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
def sections
|
28
|
+
num = 0
|
29
|
+
@doc.sections.map do |docs,code|
|
30
|
+
{
|
31
|
+
:docs => docs,
|
32
|
+
:code => code,
|
33
|
+
:num => (num += 1)
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def sources?
|
39
|
+
@doc.sources.length > 1
|
40
|
+
end
|
41
|
+
|
42
|
+
def sources
|
43
|
+
@doc.sources.sort.map do |source|
|
44
|
+
{
|
45
|
+
:path => source,
|
46
|
+
:basename => File.basename(source),
|
47
|
+
:url => relative_url(source)
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
def relative_url(source)
|
54
|
+
if(@doc.options[:preserve_urls])
|
55
|
+
source.sub(Regexp.new("#{File.extname(source)}$"), ".html")
|
56
|
+
else
|
57
|
+
relative_path = Pathname.new(File.dirname(source)).relative_path_from(Pathname(File.dirname(@doc.file))).to_s
|
58
|
+
"#{relative_path}/#{File.basename(source).sub(Regexp.new("#{File.extname(source)}$"), ".html")}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
data/lib/rokko/task.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rokko'
|
2
|
+
|
3
|
+
module Rokko
|
4
|
+
class Task
|
5
|
+
|
6
|
+
def initialize(task_name='rokko', dest='docs/', sources='lib/**/*.rb', options={})
|
7
|
+
@name = task_name
|
8
|
+
@dest = dest
|
9
|
+
@sources = FileList[sources]
|
10
|
+
@options = options
|
11
|
+
if options[:generate_index] || options[:index].is_a?(TrueClass)
|
12
|
+
@options[:generate_index] = true
|
13
|
+
end
|
14
|
+
|
15
|
+
define
|
16
|
+
end
|
17
|
+
|
18
|
+
def define
|
19
|
+
desc "Generate rokko documentation"
|
20
|
+
task @name do
|
21
|
+
# Find README file for `index.html` and delete it from `sources`
|
22
|
+
if @options[:generate_index]
|
23
|
+
readme_source = @sources.detect {|f| File.basename(f) =~ /README(\.(md|text|markdown|mdown|mkd|mkdn)$)?/i}
|
24
|
+
readme = readme_source ? File.read(@sources.delete(readme_source)) : ''
|
25
|
+
end
|
26
|
+
|
27
|
+
# Run each file through Rokko and write output
|
28
|
+
@sources.each do |filename|
|
29
|
+
rokko = Rokko.new(filename, @sources, @options)
|
30
|
+
out_dest = File.join(@dest, filename.sub(Regexp.new("#{File.extname(filename)}$"), ".html"))
|
31
|
+
puts "rokko: #{filename} -> #{out_dest}"
|
32
|
+
FileUtils.mkdir_p File.dirname(out_dest)
|
33
|
+
File.open(out_dest, 'wb') { |fd| fd.write(rokko.to_html) }
|
34
|
+
end
|
35
|
+
|
36
|
+
# Generate index.html if needed
|
37
|
+
if @options[:generate_index]
|
38
|
+
require 'rokko/index_layout'
|
39
|
+
out_dest = File.join(@dest, 'index.html')
|
40
|
+
puts "rokko: #{out_dest}"
|
41
|
+
File.open(out_dest, 'wb') {|fd| fd.write(IndexLayout.new(@sources, readme).render)}
|
42
|
+
end
|
43
|
+
|
44
|
+
# Run specified file through rokko and use it as index
|
45
|
+
if @options[:index] && source_index = @sources.delete(@options[:index])
|
46
|
+
rokko = Rokko.new(source_index, @sources, @options.merge(:preserve_urls => true))
|
47
|
+
out_dest = File.join(@dest, 'index.html')
|
48
|
+
puts "rokko: #{source_index} -> index.html"
|
49
|
+
File.open(out_dest, 'wb') {|fd| fd.write(rokko.to_html)}
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
data/lib/rokko.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
# ##Rokko -- fat-free [Rocco](http://rtomayko.github.com/rocco/)
|
2
|
+
require 'rdiscount'
|
3
|
+
|
4
|
+
module Rokko
|
5
|
+
class Rokko
|
6
|
+
attr_reader :file
|
7
|
+
attr_reader :sections
|
8
|
+
attr_reader :sources
|
9
|
+
attr_reader :options
|
10
|
+
|
11
|
+
@@comment_pattern = /^\s*#\s?/
|
12
|
+
@@block_comment_start = /^\s*=begin\s*$/
|
13
|
+
@@block_comment_end = /^\s*=end\s*$/
|
14
|
+
|
15
|
+
def initialize(filename, sources = [], options = {}, &block)
|
16
|
+
@file = filename
|
17
|
+
@sources = sources
|
18
|
+
@options = options
|
19
|
+
|
20
|
+
@data = if block_given?
|
21
|
+
yield
|
22
|
+
else
|
23
|
+
File.read(filename)
|
24
|
+
end
|
25
|
+
|
26
|
+
@sections = prettify(split(parse(@data)))
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse(data)
|
30
|
+
sections = []
|
31
|
+
docs, code = [], []
|
32
|
+
lines = data.split("\n")
|
33
|
+
|
34
|
+
# Skip shebang and encoding information
|
35
|
+
lines.shift if lines[0] =~ /^\#\!/
|
36
|
+
lines.shift if lines[0] =~ /coding[:=]\s*[-\w.]+/
|
37
|
+
|
38
|
+
in_comment_block = false
|
39
|
+
lines.each do |line|
|
40
|
+
# If we're currently in a comment block, check whether the line matches
|
41
|
+
# the _end_ of a comment block
|
42
|
+
if in_comment_block
|
43
|
+
if line.match(@@block_comment_end)
|
44
|
+
in_comment_block = false
|
45
|
+
else
|
46
|
+
docs << line
|
47
|
+
end
|
48
|
+
# Otherwise, check whether the line matches the beginning of a block, or
|
49
|
+
# a single-line comment all on it's lonesome. In either case, if there's
|
50
|
+
# code, start a new section
|
51
|
+
else
|
52
|
+
if line.match(@@block_comment_start)
|
53
|
+
in_comment_block = true
|
54
|
+
if code.any?
|
55
|
+
sections << [docs, code]
|
56
|
+
docs, code = [], []
|
57
|
+
end
|
58
|
+
elsif line.match(@@comment_pattern)
|
59
|
+
if code.any?
|
60
|
+
sections << [docs, code]
|
61
|
+
docs, code = [], []
|
62
|
+
end
|
63
|
+
docs << line.sub(@@comment_pattern, '')
|
64
|
+
else
|
65
|
+
code << line
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
sections << [docs, code] if docs.any? || code.any?
|
71
|
+
normalize_leading_spaces(sections)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Normalizes documentation whitespace by checking for leading whitespace,
|
75
|
+
# removing it, and then removing the same amount of whitespace from each
|
76
|
+
# succeeding line
|
77
|
+
def normalize_leading_spaces(sections)
|
78
|
+
sections.map do |section|
|
79
|
+
if section.any? && section[0].any?
|
80
|
+
leading_space = section[0][0].match("^\s+")
|
81
|
+
if leading_space
|
82
|
+
section[0] = section[0].map{|line| line.sub(/^#{leading_space.to_s}/, '')}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
section
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Take the list of paired *sections* two-tuples and split into two
|
90
|
+
# separate lists: one holding the comments with leaders removed and
|
91
|
+
# one with the code blocks
|
92
|
+
def split(sections)
|
93
|
+
docs_blocks, code_blocks = [], []
|
94
|
+
sections.each do |docs,code|
|
95
|
+
docs_blocks << docs.join("\n")
|
96
|
+
code_blocks << code.map do |line|
|
97
|
+
tabs = line.match(/^(\t+)/)
|
98
|
+
tabs ? line.sub(/^\t+/, ' ' * tabs.captures[0].length) : line
|
99
|
+
end.join("\n")
|
100
|
+
end
|
101
|
+
[docs_blocks, code_blocks]
|
102
|
+
end
|
103
|
+
|
104
|
+
# Take the result of `split` and apply Markdown formatting to comments
|
105
|
+
def prettify(blocks)
|
106
|
+
docs_blocks, code_blocks = blocks
|
107
|
+
|
108
|
+
# Combine all docs blocks into a single big markdown document with section
|
109
|
+
# dividers and run through the Markdown processor. Then split it back out
|
110
|
+
# into separate sections
|
111
|
+
markdown = docs_blocks.join("\n\n##### DIVIDER\n\n")
|
112
|
+
docs_html = Markdown.new(markdown, :smart).to_html.split(/\n*<h5>DIVIDER<\/h5>\n*/m)
|
113
|
+
|
114
|
+
docs_html.zip(code_blocks)
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
def to_html
|
119
|
+
require 'mustache'
|
120
|
+
$:.unshift(File.dirname(__FILE__))
|
121
|
+
require 'rokko/layout'
|
122
|
+
|
123
|
+
::Rokko::Layout.new(self).render
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
data/rokko.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rokko/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rokko"
|
7
|
+
s.version = Rokko::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Vasily Polovnyov"]
|
10
|
+
s.email = ["vasily@polovnyov.ru"]
|
11
|
+
s.homepage = "http://vast.github.com/rokko/"
|
12
|
+
s.summary = %q{Else one ruby port of [Docco](http://jashkenas.github.com/docco/)}
|
13
|
+
s.description = %q[fat-free [rocco](http://rtomayko.github.com/rocco/)]
|
14
|
+
|
15
|
+
s.rubyforge_project = "rokko"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency('mustache')
|
23
|
+
s.add_dependency('rdiscount')
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rokko
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Vasily Polovnyov
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-02-17 00:00:00 +03:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: mustache
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rdiscount
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id002
|
49
|
+
description: fat-free [rocco](http://rtomayko.github.com/rocco/)
|
50
|
+
email:
|
51
|
+
- vasily@polovnyov.ru
|
52
|
+
executables:
|
53
|
+
- rokko
|
54
|
+
extensions: []
|
55
|
+
|
56
|
+
extra_rdoc_files: []
|
57
|
+
|
58
|
+
files:
|
59
|
+
- .gitignore
|
60
|
+
- Gemfile
|
61
|
+
- README.md
|
62
|
+
- Rakefile
|
63
|
+
- TODO
|
64
|
+
- bin/rokko
|
65
|
+
- lib/rokko.rb
|
66
|
+
- lib/rokko/assets/docco.css
|
67
|
+
- lib/rokko/assets/highlight.css
|
68
|
+
- lib/rokko/assets/highlight.pack.js
|
69
|
+
- lib/rokko/index_layout.mustache
|
70
|
+
- lib/rokko/index_layout.rb
|
71
|
+
- lib/rokko/layout.mustache
|
72
|
+
- lib/rokko/layout.rb
|
73
|
+
- lib/rokko/task.rb
|
74
|
+
- lib/rokko/version.rb
|
75
|
+
- rokko.gemspec
|
76
|
+
has_rdoc: true
|
77
|
+
homepage: http://vast.github.com/rokko/
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
hash: 3
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
version: "0"
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
requirements: []
|
104
|
+
|
105
|
+
rubyforge_project: rokko
|
106
|
+
rubygems_version: 1.3.7
|
107
|
+
signing_key:
|
108
|
+
specification_version: 3
|
109
|
+
summary: Else one ruby port of [Docco](http://jashkenas.github.com/docco/)
|
110
|
+
test_files: []
|
111
|
+
|