rokko 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ Rokko -- fat-free [Rocco](http://rtomayko.github.com/rocco/)
2
+ =============================================================
3
+
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ $:.unshift(File.expand_path('lib'))
2
+ require 'rokko/task'
3
+
4
+ Rokko::Task.new(:rokko, 'docs', ['lib/**/*.rb', 'README.md'], {:index => true})
data/TODO ADDED
@@ -0,0 +1,6 @@
1
+ [ ] documentation
2
+ [ ] option for offline/online ready documentation
3
+ [x] rake task
4
+ [ ] tests
5
+ [ ] explain key differences
6
+ [ ] README and LICENSE
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,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}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 &hellip;
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 }}">&#182;</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>
@@ -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
@@ -0,0 +1,3 @@
1
+ module Rokko
2
+ VERSION = "0.0.1"
3
+ 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
+