fl-rocco 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,56 @@
1
+ class Rocco
2
+ module CommentStyles
3
+ C_STYLE_COMMENTS = {
4
+ :single => "//",
5
+ :multi => { :start => "/**", :middle => "*", :end => "*/" },
6
+ :heredoc => nil
7
+ }
8
+
9
+ COMMENT_STYLES = {
10
+ "bash" => { :single => "#", :multi => nil },
11
+ "c" => C_STYLE_COMMENTS,
12
+ "coffee-script" => {
13
+ :single => "#",
14
+ :multi => { :start => "###", :middle => nil, :end => "###" },
15
+ :heredoc => nil
16
+ },
17
+ "cpp" => C_STYLE_COMMENTS,
18
+ "csharp" => C_STYLE_COMMENTS,
19
+ "css" => {
20
+ :single => nil,
21
+ :multi => { :start => "/**", :middle => "*", :end => "*/" },
22
+ :heredoc => nil
23
+ },
24
+ "html" => {
25
+ :single => nil,
26
+ :multi => { :start => '<!--', :middle => nil, :end => '-->' },
27
+ :heredoc => nil
28
+ },
29
+ "java" => C_STYLE_COMMENTS,
30
+ "js" => C_STYLE_COMMENTS,
31
+ "lua" => {
32
+ :single => "--",
33
+ :multi => nil,
34
+ :heredoc => nil
35
+ },
36
+ "php" => C_STYLE_COMMENTS,
37
+ "python" => {
38
+ :single => "#",
39
+ :multi => { :start => '"""', :middle => nil, :end => '"""' },
40
+ :heredoc => nil
41
+ },
42
+ "rb" => {
43
+ :single => "#",
44
+ :multi => { :start => '=begin', :middle => nil, :end => '=end' },
45
+ :heredoc => "<<-"
46
+ },
47
+ "scala" => C_STYLE_COMMENTS,
48
+ "scheme" => { :single => ";;", :multi => nil, :heredoc => nil },
49
+ "xml" => {
50
+ :single => nil,
51
+ :multi => { :start => '<!--', :middle => nil, :end => '-->' },
52
+ :heredoc => nil
53
+ },
54
+ }
55
+ end
56
+ end
@@ -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="{{ stylesheet }}">
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,64 @@
1
+ require 'mustache'
2
+ require 'pathname'
3
+
4
+ class Rocco::Layout < Mustache
5
+ self.template_path = "#{File.dirname(__FILE__)}/.."
6
+
7
+ def initialize(doc, stylesheet, file=nil)
8
+ @doc = doc
9
+ @stylesheet = stylesheet
10
+ if not file.nil?
11
+ Rocco::Layout.template_file = file
12
+ end
13
+ end
14
+
15
+ def title
16
+ File.basename(@doc.file)
17
+ end
18
+
19
+ def stylesheet
20
+ @stylesheet
21
+ end
22
+
23
+ def file
24
+ @doc.file
25
+ end
26
+
27
+ def sections
28
+ num = 0
29
+ @doc.sections.map do |docs,code|
30
+ code ||= ''
31
+ is_header = /^<h.>(.+)<\/h.>$/.match( docs )
32
+ header_text = is_header && is_header[1].split.join("_")
33
+ num += 1
34
+ {
35
+ :docs => docs,
36
+ :docs? => !docs.empty?,
37
+ :header? => is_header,
38
+
39
+ :code => code,
40
+ :code? => !code.empty?,
41
+
42
+ :empty? => ( code.empty? && docs.empty? ),
43
+ :section_id => is_header ? header_text : num
44
+ }
45
+ end
46
+ end
47
+
48
+ def sources?
49
+ @doc.sources.length > 1
50
+ end
51
+
52
+ def sources
53
+ currentpath = Pathname.new( File.dirname( @doc.file ) )
54
+ @doc.sources.sort.map do |source|
55
+ htmlpath = Pathname.new( source.sub( Regexp.new( "#{File.extname(source)}$"), ".html" ) )
56
+
57
+ {
58
+ :path => source,
59
+ :basename => File.basename(source),
60
+ :url => htmlpath.relative_path_from( currentpath )
61
+ }
62
+ end
63
+ end
64
+ 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 if defined?(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,3 @@
1
+ class Rocco
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,65 @@
1
+ # rocco.gemspec
2
+ #
3
+ # To update this file's version, date, and file list, change the VERSION
4
+ # constant in lib/rocco.rb and run `rake rocco.gemspec`.
5
+
6
+ Gem::Specification.new do |s|
7
+ s.specification_version = 2 if s.respond_to? :specification_version=
8
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
+
10
+ s.name = 'fl-rocco'
11
+ s.version = '1.0.0'
12
+ s.date = '2012-01-10'
13
+
14
+ s.description = "Docco in Ruby"
15
+ s.summary = s.description
16
+
17
+ s.authors = ["Ryan Tomayko", "Mike West"]
18
+ s.email = ["r@tomayko.com", "<mike@mikewest.org>"]
19
+
20
+ # = MANIFEST =
21
+ s.files = %w[
22
+ CHANGES.md
23
+ COPYING
24
+ README
25
+ Rakefile
26
+ bin/rocco
27
+ lib/rocco.rb
28
+ lib/rocco/comment_styles.rb
29
+ lib/rocco/layout.mustache
30
+ lib/rocco/layout.rb
31
+ lib/rocco/tasks.rb
32
+ lib/rocco/version.rb
33
+ rocco.gemspec
34
+ test/fixtures/issue10.iso-8859-1.rb
35
+ test/fixtures/issue10.utf-8.rb
36
+ test/helper.rb
37
+ test/suite.rb
38
+ test/test_basics.rb
39
+ test/test_block_comment_styles.rb
40
+ test/test_block_comments.rb
41
+ test/test_comment_normalization.rb
42
+ test/test_commentchar_detection.rb
43
+ test/test_descriptive_section_names.rb
44
+ test/test_docblock_annotations.rb
45
+ test/test_heredoc.rb
46
+ test/test_language_detection.rb
47
+ test/test_reported_issues.rb
48
+ test/test_skippable_lines.rb
49
+ test/test_source_list.rb
50
+ test/test_stylesheet.rb
51
+ ]
52
+ # = MANIFEST =
53
+
54
+ s.executables = ["rocco"]
55
+
56
+ s.test_files = s.files.select {|path| path =~ /^test\/.*_test.rb/}
57
+ s.add_dependency 'redcarpet', '~> 1.17'
58
+ s.add_dependency 'mustache'
59
+ s.add_development_dependency 'rake', '~> 0.9'
60
+
61
+ s.has_rdoc = false
62
+ s.homepage = "http://rtomayko.github.com/rocco/"
63
+ s.require_paths = %w[lib]
64
+ s.rubygems_version = '1.1.1'
65
+ end
@@ -0,0 +1 @@
1
+ # hello w�rld
@@ -0,0 +1 @@
1
+ # hello ąćęłńóśźż
@@ -0,0 +1,25 @@
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
21
+
22
+ def fb_assert_val( str )
23
+ return str.strip if Rocco::MD_BLUECLOTH
24
+ str
25
+ 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 fb_assert_val("<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