rokko 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+