dkastner-rocco 0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,46 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
5
+ <title>{{ title }}</title>
6
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
7
+ </head>
8
+ <body>
9
+ <div id='container'>
10
+ <div id="background"></div>
11
+ {{#sources?}}
12
+ <div id="jump_to">
13
+ Jump To &hellip;
14
+ <div id="jump_wrapper">
15
+ <div id="jump_page">
16
+ {{#sources}}
17
+ <a class="source" href="{{ url }}">{{ basename }}</a>
18
+ {{/sources}}
19
+ </div>
20
+ </div>
21
+ </div>
22
+ {{/sources?}}
23
+ <table cellspacing=0 cellpadding=0>
24
+ <thead>
25
+ <tr>
26
+ <th class=docs><h1>{{ title }}</h1></th>
27
+ <th class=code></th>
28
+ </tr>
29
+ </thead>
30
+ <tbody>
31
+ {{#sections}}
32
+ <tr id='section-{{ section_id }}'>
33
+ <td class=docs>
34
+ <div class="pilwrap">
35
+ <a class="pilcrow" href="#section-{{ section_id }}">&#182;</a>
36
+ </div>
37
+ {{{ docs }}}
38
+ </td>
39
+ <td class=code>
40
+ <div class='highlight'><pre>{{{ code }}}</pre></div>
41
+ </td>
42
+ </tr>
43
+ {{/sections}}
44
+ </table>
45
+ </div>
46
+ </body>
@@ -0,0 +1,54 @@
1
+ require 'mustache'
2
+ require 'pathname'
3
+
4
+ class Rocco::Layout < Mustache
5
+ self.template_path = "#{File.dirname(__FILE__)}/.."
6
+
7
+ def initialize(doc, file=nil)
8
+ @doc = doc
9
+ if not file.nil?
10
+ Rocco::Layout.template_file = file
11
+ end
12
+ end
13
+
14
+ def title
15
+ File.basename(@doc.file)
16
+ end
17
+
18
+ def sections
19
+ num = 0
20
+ @doc.sections.map do |docs,code|
21
+ is_header = /^<h.>(.+)<\/h.>$/.match( docs )
22
+ header_text = is_header && is_header[1].split.join("_")
23
+ num += 1
24
+ {
25
+ :docs => docs,
26
+ :docs? => !docs.empty?,
27
+ :header? => is_header,
28
+
29
+ :code => code,
30
+ :code? => !code.empty?,
31
+
32
+ :empty? => ( code.empty? && docs.empty? ),
33
+ :section_id => is_header ? header_text : num
34
+ }
35
+ end
36
+ end
37
+
38
+ def sources?
39
+ @doc.sources.length > 1
40
+ end
41
+
42
+ def sources
43
+ currentpath = Pathname.new( File.dirname( @doc.file ) )
44
+ @doc.sources.sort.map do |source|
45
+ htmlpath = Pathname.new( source.sub( Regexp.new( "#{File.extname(source)}$"), ".html" ) )
46
+
47
+ {
48
+ :path => source,
49
+ :basename => File.basename(source),
50
+ :url => htmlpath.relative_path_from( currentpath )
51
+ }
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,123 @@
1
+ #### Rocco Rake Tasks
2
+ #
3
+ # To use the Rocco Rake tasks, require `rocco/tasks` in your `Rakefile`
4
+ # and define a Rake task with `rocco_task`. In its simplest form, `rocco_task`
5
+ # takes the path to a destination directory where HTML docs should be built:
6
+ #
7
+ # require 'rocco/tasks'
8
+ #
9
+ # desc "Build Rocco Docs"
10
+ # Rocco::make 'docs/'
11
+ #
12
+ # This creates a `:rocco` rake task, which can then be run with:
13
+ #
14
+ # rake rocco
15
+ #
16
+ # It's a good idea to guard against Rocco not being available, since your
17
+ # Rakefile will fail to load otherwise. Consider doing something like this,
18
+ # so that your Rakefile will still work
19
+ #
20
+ # begin
21
+ # require 'rocco/tasks'
22
+ # Rocco::make 'docs/'
23
+ # rescue LoadError
24
+ # warn "#$! -- rocco tasks not loaded."
25
+ # task :rocco
26
+ # end
27
+ #
28
+ # It's also possible to pass a glob pattern:
29
+ #
30
+ # Rocco::make 'html/', 'lib/thing/**/*.rb'
31
+ #
32
+ # Or a list of glob patterns:
33
+ #
34
+ # Rocco::make 'html/', ['lib/thing.rb', 'lib/thing/*.rb']
35
+ #
36
+ # Finally, it is also possible to specify which Pygments language you would
37
+ # like to use to highlight the code, as well as the comment characters for the
38
+ # language in the `options` hash:
39
+ #
40
+ # Rocco::make 'html/', 'lib/thing/**/*.rb', {
41
+ # :language => 'io',
42
+ # :comment_chars => '#'
43
+ # }
44
+ #
45
+
46
+ # Might be nice to defer this until we actually need to build docs but this
47
+ # will have to do for now.
48
+ require 'rocco'
49
+
50
+ # Reopen the Rocco class and add a `make` class method. This is a simple bit
51
+ # of sugar over `Rocco::Task.new`. If you want your Rake task to be named
52
+ # something other than `:rocco`, you can use `Rocco::Task` directly.
53
+ class Rocco
54
+ def self.make(dest='docs/', source_files='lib/**/*.rb', options={})
55
+ Task.new(:rocco, dest, source_files, options)
56
+ end
57
+
58
+ # `Rocco::Task.new` takes a task name, the destination directory docs
59
+ # should be built under, and a source file pattern or file list.
60
+ class Task
61
+ include Rake::DSL
62
+
63
+ def initialize(task_name, dest='docs/', sources='lib/**/*.rb', options={})
64
+ @name = task_name
65
+ @dest = dest[-1] == ?/ ? dest : "#{dest}/"
66
+ @sources = FileList[sources]
67
+ @options = options
68
+
69
+ # Make sure there's a `directory` task defined for our destination.
70
+ define_directory_task @dest
71
+
72
+ # Run over the source file list, constructing destination filenames
73
+ # and defining file tasks.
74
+ @sources.each do |source_file|
75
+ dest_file = source_file.sub(Regexp.new("#{File.extname(source_file)}$"), ".html")
76
+ define_file_task source_file, "#{@dest}#{dest_file}"
77
+
78
+ # If `rake/clean` was required, add the generated files to the list.
79
+ # That way all Rocco generated are removed when running `rake clean`.
80
+ CLEAN.include "#{@dest}#{dest_file}" if defined? CLEAN
81
+ end
82
+ end
83
+
84
+ # Define the destination directory task and make the `:rocco` task depend
85
+ # on it. This causes the destination directory to be created if it doesn't
86
+ # already exist.
87
+ def define_directory_task(path)
88
+ directory path
89
+ task @name => path
90
+ end
91
+
92
+ # Setup a `file` task for a single Rocco output file (`dest_file`). It
93
+ # depends on the source file, the destination directory, and all of Rocco's
94
+ # internal source code, so that the destination file is rebuilt when any of
95
+ # those changes.
96
+ #
97
+ # You can run these tasks directly with Rake:
98
+ #
99
+ # rake docs/foo.html docs/bar.html
100
+ #
101
+ # ... would generate the `foo.html` and `bar.html` files but only if they
102
+ # don't already exist or one of their dependencies was changed.
103
+ def define_file_task(source_file, dest_file)
104
+ prerequisites = [@dest, source_file] + rocco_source_files
105
+ file dest_file => prerequisites do |f|
106
+ verbose { puts "rocco: #{source_file} -> #{dest_file}" }
107
+ rocco = Rocco.new(source_file, @sources.to_a, @options)
108
+ FileUtils.mkdir_p(File.dirname(dest_file))
109
+ File.open(dest_file, 'wb') { |fd| fd.write(rocco.to_html) }
110
+ end
111
+ task @name => dest_file
112
+ end
113
+
114
+ # Return a `FileList` that includes all of Roccos source files. This causes
115
+ # output files to be regenerated properly when someone upgrades the Rocco
116
+ # library.
117
+ def rocco_source_files
118
+ libdir = File.expand_path('../..', __FILE__)
119
+ FileList["#{libdir}/rocco.rb", "#{libdir}/rocco/**"]
120
+ end
121
+
122
+ end
123
+ end
@@ -0,0 +1,54 @@
1
+ Gem::Specification.new do |s|
2
+ s.specification_version = 2 if s.respond_to? :specification_version=
3
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
+
5
+ s.name = 'dkastner-rocco'
6
+ s.version = '0.8'
7
+ s.date = '2011-05-24'
8
+
9
+ s.description = "Docco in Ruby"
10
+ s.summary = s.description
11
+
12
+ s.authors = ["Ryan Tomayko", "Mike West"]
13
+ s.email = ["r@tomayko.com", "<mike@mikewest.org>"]
14
+
15
+ # = MANIFEST =
16
+ s.files = %w[
17
+ CHANGES.md
18
+ COPYING
19
+ README
20
+ Rakefile
21
+ bin/rocco
22
+ lib/rocco.rb
23
+ lib/rocco/layout.mustache
24
+ lib/rocco/layout.rb
25
+ lib/rocco/tasks.rb
26
+ rocco.gemspec
27
+ test/fixtures/issue10.iso-8859-1.rb
28
+ test/fixtures/issue10.utf-8.rb
29
+ test/helper.rb
30
+ test/suite.rb
31
+ test/test_basics.rb
32
+ test/test_block_comments.rb
33
+ test/test_comment_normalization.rb
34
+ test/test_commentchar_detection.rb
35
+ test/test_descriptive_section_names.rb
36
+ test/test_language_detection.rb
37
+ test/test_reported_issues.rb
38
+ test/test_skippable_lines.rb
39
+ test/test_source_list.rb
40
+ ]
41
+ # = MANIFEST =
42
+
43
+ s.executables = ["rocco"]
44
+
45
+ s.test_files = s.files.select {|path| path =~ /^test\/.*_test.rb/}
46
+ s.add_dependency 'rdiscount'
47
+ s.add_dependency 'mustache'
48
+ s.add_development_dependency 'rake', '>= 0.9.0'
49
+
50
+ s.has_rdoc = false
51
+ s.homepage = "http://rtomayko.github.com/rocco/"
52
+ s.require_paths = %w[lib]
53
+ s.rubygems_version = '1.1.1'
54
+ end
@@ -0,0 +1 @@
1
+ # hello w�rld
@@ -0,0 +1 @@
1
+ # hello ąćęłńóśźż
@@ -0,0 +1,20 @@
1
+ rootdir = File.expand_path('../../lib', __FILE__)
2
+ $LOAD_PATH.unshift "#{rootdir}/lib"
3
+
4
+ require 'test/unit'
5
+ begin; require 'turn'; rescue LoadError; end
6
+ begin
7
+ require 'rdiscount'
8
+ rescue LoadError
9
+ if !defined?(Gem)
10
+ require 'rubygems'
11
+ retry
12
+ end
13
+ end
14
+ require 'rocco'
15
+
16
+ def roccoize( filename, contents, options = {} )
17
+ Rocco.new( filename, [ filename ], options ) {
18
+ contents
19
+ }
20
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+ require 'test/unit'
3
+
4
+ Dir[File.expand_path('../test_*.rb', __FILE__)].
5
+ each { |file| require file }
@@ -0,0 +1,63 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class RoccoBasicTests < Test::Unit::TestCase
4
+ def test_rocco_exists_and_is_instancable
5
+ roccoize( "filename.rb", "# Comment 1\ndef codeblock\nend\n" )
6
+ end
7
+
8
+ def test_filename
9
+ r = roccoize( "filename.rb", "# Comment 1\ndef codeblock\nend\n" )
10
+ assert_equal "filename.rb", r.file
11
+ end
12
+
13
+ def test_sources
14
+ r = roccoize( "filename.rb", "# Comment 1\ndef codeblock\nend\n" )
15
+ assert_equal [ "filename.rb" ], r.sources
16
+ end
17
+
18
+ def test_sections
19
+ r = roccoize( "filename.rb", "# Comment 1\ndef codeblock\nend\n" )
20
+ assert_equal 1, r.sections.length
21
+ assert_equal 2, r.sections[ 0 ].length
22
+ assert_equal "<p>Comment 1</p>\n", r.sections[ 0 ][ 0 ]
23
+ assert_equal "<span class=\"k\">def</span> <span class=\"nf\">codeblock</span>\n<span class=\"k\">end</span>", r.sections[ 0 ][ 1 ]
24
+ end
25
+
26
+ def test_parsing
27
+ r = Rocco.new( 'test' ) { "" } # Generate throwaway instance so I can test `parse`
28
+ assert_equal(
29
+ [
30
+ [ [ "Comment 1" ], [ "def codeblock", "end" ] ]
31
+ ],
32
+ r.parse( "# Comment 1\ndef codeblock\nend\n" )
33
+ )
34
+ assert_equal(
35
+ [
36
+ [ [ "Comment 1" ], [ "def codeblock" ] ],
37
+ [ [ "Comment 2" ], [ "end" ] ]
38
+ ],
39
+ r.parse( "# Comment 1\ndef codeblock\n# Comment 2\nend\n" )
40
+ )
41
+ end
42
+
43
+ def test_splitting
44
+ r = Rocco.new( 'test' ) { "" } # Generate throwaway instance so I can test `split`
45
+ assert_equal(
46
+ [
47
+ [ "Comment 1" ],
48
+ [ "def codeblock\nend" ]
49
+ ],
50
+ r.split([ [ [ "Comment 1" ], [ "def codeblock", "end" ] ] ])
51
+ )
52
+ assert_equal(
53
+ [
54
+ [ "Comment 1", "Comment 2" ],
55
+ [ "def codeblock", "end" ]
56
+ ],
57
+ r.split( [
58
+ [ [ "Comment 1" ], [ "def codeblock" ] ],
59
+ [ [ "Comment 2" ], [ "end" ] ]
60
+ ] )
61
+ )
62
+ end
63
+ end
@@ -0,0 +1,101 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class RoccoBlockCommentTest < Test::Unit::TestCase
4
+ def test_basics
5
+ r = Rocco.new( 'test', '', { :language => "c" } ) { "" } # Generate throwaway instance so I can test `parse`
6
+ assert_equal(
7
+ [
8
+ [ [ "Comment 1" ], [ "def codeblock", "end" ] ]
9
+ ],
10
+ r.parse( "/**\n * Comment 1\n */\ndef codeblock\nend\n" )
11
+ )
12
+ assert_equal(
13
+ [
14
+ [ [ "Comment 1a", "Comment 1b" ], [ "def codeblock", "end" ] ]
15
+ ],
16
+ r.parse( "/**\n * Comment 1a\n * Comment 1b\n */\ndef codeblock\nend\n" )
17
+ )
18
+ end
19
+
20
+ def test_multiple_blocks
21
+ r = Rocco.new( 'test', '', { :language => "c" } ) { "" } # Generate throwaway instance so I can test `parse`
22
+ assert_equal(
23
+ [
24
+ [ [ "Comment 1" ], [ "def codeblock", "end" ] ],
25
+ [ [ "Comment 2" ], [] ]
26
+ ],
27
+ r.parse( "/**\n * Comment 1\n */\ndef codeblock\nend\n/**\n * Comment 2\n */\n" )
28
+ )
29
+ assert_equal(
30
+ [
31
+ [ [ "Comment 1" ], [ "def codeblock", "end" ] ],
32
+ [ [ "Comment 2" ], [ "if false", "end" ] ]
33
+ ],
34
+ r.parse( "/**\n * Comment 1\n */\ndef codeblock\nend\n/**\n * Comment 2\n */\nif false\nend" )
35
+ )
36
+ end
37
+
38
+ def test_block_without_middle_character
39
+ r = Rocco.new( 'test', '', { :language => "python" } ) { "" } # Generate throwaway instance so I can test `parse`
40
+ assert_equal(
41
+ [
42
+ [ [ "Comment 1" ], [ "def codeblock", "end" ] ],
43
+ [ [ "Comment 2" ], [] ]
44
+ ],
45
+ r.parse( "\"\"\"\n Comment 1\n\"\"\"\ndef codeblock\nend\n\"\"\"\n Comment 2\n\"\"\"\n" )
46
+ )
47
+ assert_equal(
48
+ [
49
+ [ [ "Comment 1" ], [ "def codeblock", "end" ] ],
50
+ [ [ "Comment 2" ], [ "if false", "end" ] ]
51
+ ],
52
+ r.parse( "\"\"\"\n Comment 1\n\"\"\"\ndef codeblock\nend\n\"\"\"\n Comment 2\n\"\"\"\nif false\nend" )
53
+ )
54
+ end
55
+
56
+ def test_language_without_single_line_comments_parse
57
+ r = Rocco.new( 'test', '', { :language => "css" } ) { "" } # Generate throwaway instance so I can test `parse`
58
+ assert_equal(
59
+ [
60
+ [ [ "Comment 1" ], [ "def codeblock", "end" ] ],
61
+ [ [ "Comment 2" ], [ "if false", "end" ] ]
62
+ ],
63
+ r.parse( "/**\n * Comment 1\n */\ndef codeblock\nend\n/**\n * Comment 2\n */\nif false\nend" )
64
+ )
65
+ end
66
+
67
+ def test_language_without_single_line_comments_split
68
+ r = Rocco.new( 'test', '', { :language => "css" } ) { "" } # Generate throwaway instance so I can test `parse`
69
+ assert_equal(
70
+ [
71
+ [ "Comment 1", "Comment 2" ],
72
+ [ "def codeblock\nend", "if false\nend" ]
73
+ ],
74
+ r.split( [
75
+ [ [ "Comment 1" ], [ "def codeblock", "end" ] ],
76
+ [ [ "Comment 2" ], [ "if false", "end" ] ]
77
+ ] )
78
+ )
79
+ end
80
+
81
+ def test_language_without_single_line_comments_highlight
82
+ r = Rocco.new( 'test', '', { :language => "css" } ) { "" } # Generate throwaway instance so I can test `parse`
83
+
84
+ highlighted = r.highlight( r.split( r.parse( "/**\n * This is a comment!\n */\n.rule { goes: here; }\n/**\n * Comment 2\n */\n.rule2 { goes: here; }" ) ) )
85
+ assert_equal(
86
+ "<p>This is a comment!</p>",
87
+ highlighted[0][0]
88
+ )
89
+ assert_equal(
90
+ "<p>Comment 2</p>\n",
91
+ highlighted[1][0]
92
+ )
93
+ assert(
94
+ !highlighted[0][1].include?("DIVIDER") &&
95
+ !highlighted[1][1].include?("DIVIDER"),
96
+ "`DIVIDER` stripped successfully."
97
+ )
98
+ assert( true )
99
+ end
100
+
101
+ end