murdoc 0.1.0
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/.document +5 -0
- data/.rspec +2 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +31 -0
- data/README.md +19 -0
- data/Rakefile +48 -0
- data/UNLICENSE +24 -0
- data/VERSION +1 -0
- data/autotest/discover.rb +1 -0
- data/bin/murdoc +24 -0
- data/lib/murdoc.rb +25 -0
- data/lib/murdoc/annotator.rb +112 -0
- data/lib/murdoc/formatter.rb +19 -0
- data/lib/murdoc/languages/javascript.rb +43 -0
- data/lib/murdoc/languages/ruby.rb +43 -0
- data/lib/murdoc/paragraph.rb +50 -0
- data/markup/stylesheet.css +241 -0
- data/markup/template.haml +15 -0
- data/murdoc.gemspec +88 -0
- data/spec/murdoc/annotator_spec.rb +111 -0
- data/spec/murdoc/formatter_spec.rb +27 -0
- data/spec/murdoc/paragraph_spec.rb +21 -0
- data/spec/spec_helper.rb +5 -0
- metadata +192 -0
    
        data/.document
    ADDED
    
    
    
        data/.rspec
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            GEM
         | 
| 2 | 
            +
              remote: http://rubygems.org/
         | 
| 3 | 
            +
              specs:
         | 
| 4 | 
            +
                diff-lcs (1.1.2)
         | 
| 5 | 
            +
                git (1.2.5)
         | 
| 6 | 
            +
                haml (3.0.24)
         | 
| 7 | 
            +
                jeweler (1.5.1)
         | 
| 8 | 
            +
                  bundler (~> 1.0.0)
         | 
| 9 | 
            +
                  git (>= 1.2.5)
         | 
| 10 | 
            +
                  rake
         | 
| 11 | 
            +
                rake (0.8.7)
         | 
| 12 | 
            +
                rdiscount (1.6.5)
         | 
| 13 | 
            +
                rspec (2.1.0)
         | 
| 14 | 
            +
                  rspec-core (~> 2.1.0)
         | 
| 15 | 
            +
                  rspec-expectations (~> 2.1.0)
         | 
| 16 | 
            +
                  rspec-mocks (~> 2.1.0)
         | 
| 17 | 
            +
                rspec-core (2.1.0)
         | 
| 18 | 
            +
                rspec-expectations (2.1.0)
         | 
| 19 | 
            +
                  diff-lcs (~> 1.1.2)
         | 
| 20 | 
            +
                rspec-mocks (2.1.0)
         | 
| 21 | 
            +
                sass (3.1.0.alpha.39)
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            PLATFORMS
         | 
| 24 | 
            +
              ruby
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            DEPENDENCIES
         | 
| 27 | 
            +
              haml (~> 3.0.0)
         | 
| 28 | 
            +
              jeweler
         | 
| 29 | 
            +
              rdiscount (~> 1.6.5)
         | 
| 30 | 
            +
              rspec (~> 2.1.0)
         | 
| 31 | 
            +
              sass (~> 3.1.0)
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            Murdoc -- evil ruby documenter
         | 
| 2 | 
            +
            ==============================
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            Murdoc is a doccu-style annotated documentation generator.
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            You may also want to see:
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            * [docco.coffee](http://jashkenas.github.com/docco/)
         | 
| 9 | 
            +
            * [Rocco](http://rtomayko.github.com/rocco/)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            Example
         | 
| 12 | 
            +
            =======
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            See example at [GH.pages](http://markiz.github.com/murdoc).
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            License and authorship
         | 
| 17 | 
            +
            ======================
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            Murdoc is originally authored by Mark Abramov and belongs to public domain (see UNLICENSE for details).
         | 
    
        data/Rakefile
    ADDED
    
    | @@ -0,0 +1,48 @@ | |
| 1 | 
            +
            require 'rubygems'
         | 
| 2 | 
            +
            require 'bundler'
         | 
| 3 | 
            +
            begin
         | 
| 4 | 
            +
              Bundler.setup(:default, :development)
         | 
| 5 | 
            +
            rescue Bundler::BundlerError => e
         | 
| 6 | 
            +
              $stderr.puts e.message
         | 
| 7 | 
            +
              $stderr.puts "Run `bundle install` to install missing gems"
         | 
| 8 | 
            +
              exit e.status_code
         | 
| 9 | 
            +
            end
         | 
| 10 | 
            +
            require 'rake'
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            require 'jeweler'
         | 
| 13 | 
            +
            Jeweler::Tasks.new do |gem|
         | 
| 14 | 
            +
              # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
         | 
| 15 | 
            +
              gem.name = "murdoc"
         | 
| 16 | 
            +
              gem.homepage = "http://github.com/markiz/murdoc"
         | 
| 17 | 
            +
              gem.license = "Public Domain"
         | 
| 18 | 
            +
              gem.summary = "Annotated documentation generator"
         | 
| 19 | 
            +
              gem.description = "Annotated documentation generator, see README.md for details"
         | 
| 20 | 
            +
              gem.email = "markizko@gmail.com"
         | 
| 21 | 
            +
              gem.authors = ["Mark Abramov"]
         | 
| 22 | 
            +
              gem.add_runtime_dependency "haml", "~> 3.0.0"
         | 
| 23 | 
            +
              gem.add_runtime_dependency "rdiscount", "~> 1.6.5"
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
            Jeweler::RubygemsDotOrgTasks.new
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            require 'rspec/core'
         | 
| 28 | 
            +
            require 'rspec/core/rake_task'
         | 
| 29 | 
            +
            RSpec::Core::RakeTask.new(:spec) do |spec|
         | 
| 30 | 
            +
              spec.pattern = FileList['spec/**/*_spec.rb']
         | 
| 31 | 
            +
            end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            RSpec::Core::RakeTask.new(:rcov) do |spec|
         | 
| 34 | 
            +
              spec.pattern = 'spec/**/*_spec.rb'
         | 
| 35 | 
            +
              spec.rcov = true
         | 
| 36 | 
            +
            end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            task :default => :spec
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            require 'rake/rdoctask'
         | 
| 41 | 
            +
            Rake::RDocTask.new do |rdoc|
         | 
| 42 | 
            +
              version = File.exist?('VERSION') ? File.read('VERSION') : ""
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              rdoc.rdoc_dir = 'rdoc'
         | 
| 45 | 
            +
              rdoc.title = "murdoc #{version}"
         | 
| 46 | 
            +
              rdoc.rdoc_files.include('README*')
         | 
| 47 | 
            +
              rdoc.rdoc_files.include('lib/**/*.rb')
         | 
| 48 | 
            +
            end
         | 
    
        data/UNLICENSE
    ADDED
    
    | @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            This is free and unencumbered software released into the public domain.
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Anyone is free to copy, modify, publish, use, compile, sell, or
         | 
| 4 | 
            +
            distribute this software, either in source code form or as a compiled
         | 
| 5 | 
            +
            binary, for any purpose, commercial or non-commercial, and by any
         | 
| 6 | 
            +
            means.
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            In jurisdictions that recognize copyright laws, the author or authors
         | 
| 9 | 
            +
            of this software dedicate any and all copyright interest in the
         | 
| 10 | 
            +
            software to the public domain. We make this dedication for the benefit
         | 
| 11 | 
            +
            of the public at large and to the detriment of our heirs and
         | 
| 12 | 
            +
            successors. We intend this dedication to be an overt act of
         | 
| 13 | 
            +
            relinquishment in perpetuity of all present and future rights to this
         | 
| 14 | 
            +
            software under copyright law.
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 17 | 
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 18 | 
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
         | 
| 19 | 
            +
            IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
         | 
| 20 | 
            +
            OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
         | 
| 21 | 
            +
            ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
         | 
| 22 | 
            +
            OTHER DEALINGS IN THE SOFTWARE.
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            For more information, please refer to <http://unlicense.org/>
         | 
    
        data/VERSION
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            0.1.0
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            Autotest.add_discovery { "rspec2" }
         | 
    
        data/bin/murdoc
    ADDED
    
    | @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
            require "optparse"
         | 
| 3 | 
            +
            $: << "./lib/"
         | 
| 4 | 
            +
            require "murdoc"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
             | 
| 7 | 
            +
             | 
| 8 | 
            +
            option_parser = OptionParser.new do |opts|
         | 
| 9 | 
            +
              opts.banner = "murdoc <input file> <output html>"  
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              opts.on_tail("-h", "--help", "Show this message") do
         | 
| 12 | 
            +
                puts opts
         | 
| 13 | 
            +
                exit
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            option_parser.parse!
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            if ARGV.size < 2
         | 
| 21 | 
            +
              puts option_parser
         | 
| 22 | 
            +
            else
         | 
| 23 | 
            +
              Murdoc.generate_from_file(ARGV[0], ARGV[1])
         | 
| 24 | 
            +
            end
         | 
    
        data/lib/murdoc.rb
    ADDED
    
    | @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            #
         | 
| 2 | 
            +
            # Murdoc is *yet another* Doccu-like documentation generator.
         | 
| 3 | 
            +
            # Murdoc reads ruby source files and produces annotated html documentation.
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            # See also: [Docco][do], [Rocco][ro]
         | 
| 6 | 
            +
            #
         | 
| 7 | 
            +
            # [do]: "http://jashkenas.github.com/docco/"
         | 
| 8 | 
            +
            # [ro]: "http://rtomayko.github.com/rocco"
         | 
| 9 | 
            +
            #
         | 
| 10 | 
            +
             | 
| 11 | 
            +
             | 
| 12 | 
            +
            module Murdoc
         | 
| 13 | 
            +
              def self.generate_from_file(input, output)
         | 
| 14 | 
            +
                annotator = Annotator.from_file(input)
         | 
| 15 | 
            +
                File.open(output, "w+") do |f|
         | 
| 16 | 
            +
                  f.puts Formatter.new("markup/template.haml").render(:paragraphs => annotator.paragraphs, :stylesheet => File.read("markup/stylesheet.css"))
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            require "murdoc/annotator"
         | 
| 22 | 
            +
            require "murdoc/paragraph"
         | 
| 23 | 
            +
            require "murdoc/formatter"
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            Dir["#{File.dirname(File.expand_path(__FILE__))}/murdoc/languages/*.rb"].each {|lang| require lang }
         | 
| @@ -0,0 +1,112 @@ | |
| 1 | 
            +
            # Annotator class does all the main job: parses out comments
         | 
| 2 | 
            +
            # and returns annotated code
         | 
| 3 | 
            +
             | 
| 4 | 
            +
             | 
| 5 | 
            +
            # Main module
         | 
| 6 | 
            +
            module Murdoc
         | 
| 7 | 
            +
              class Annotator
         | 
| 8 | 
            +
                # Attribute accessor containing the resulting paragraphs
         | 
| 9 | 
            +
                attr_accessor :paragraphs
         | 
| 10 | 
            +
             | 
| 11 | 
            +
             | 
| 12 | 
            +
                # `source` string contains annotated source code
         | 
| 13 | 
            +
                # `source_type` is one of supported source types (currently `[:ruby, :javascript]`)
         | 
| 14 | 
            +
                def initialize(source, source_type)
         | 
| 15 | 
            +
                  self.source_type = source_type
         | 
| 16 | 
            +
                  self.source      = source
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                # You may also initialize annotator from file, it will even try to detect the
         | 
| 20 | 
            +
                # source type from extension.
         | 
| 21 | 
            +
                def self.from_file(filename, source_type = nil)
         | 
| 22 | 
            +
                  self.new(File.read(filename), source_type || detect_source_type_from_filename(filename))
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def source_type
         | 
| 26 | 
            +
                  @source_type
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def source_type=(source_type)
         | 
| 30 | 
            +
                  @source_type = source_type.to_s
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                # Big and hairy code parser
         | 
| 34 | 
            +
                def source=(src)
         | 
| 35 | 
            +
                  @source = src
         | 
| 36 | 
            +
                  @paragraphs = []
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  # Lambda for checking source for comments. Used for getting consequent non-comments
         | 
| 39 | 
            +
                  # into resulting stream
         | 
| 40 | 
            +
                  is_comment = lambda do |line|
         | 
| 41 | 
            +
                    result = false
         | 
| 42 | 
            +
                    # If source supports single line comments
         | 
| 43 | 
            +
                    if comment_symbols[:single_line]
         | 
| 44 | 
            +
                      result ||= line =~ /^\s*#{Regexp.escape(comment_symbols[:single_line])}/
         | 
| 45 | 
            +
                    end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    # If source supports multi-line comments
         | 
| 48 | 
            +
                    if comment_symbols[:multiline]
         | 
| 49 | 
            +
                      result ||= line =~ /^\s*#{Regexp.escape(comment_symbols[:multiline][:begin])}/
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
                    result
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  # splitting stuff into lines and setting cursor into initial position
         | 
| 55 | 
            +
                  lines = src.split("\n")
         | 
| 56 | 
            +
                  i = 0
         | 
| 57 | 
            +
                  while i < lines.size
         | 
| 58 | 
            +
                    comment_lines = []
         | 
| 59 | 
            +
                    # get single line comments (removing optional first space after comment symbol)
         | 
| 60 | 
            +
                    if comment_symbols[:single_line]
         | 
| 61 | 
            +
                      while i < lines.size && lines[i] =~ /^\s*#{Regexp.escape(comment_symbols[:single_line])}\s?(.*)/
         | 
| 62 | 
            +
                        comment_lines << $1
         | 
| 63 | 
            +
                        i += 1
         | 
| 64 | 
            +
                      end
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    # getting multiline comments
         | 
| 68 | 
            +
                    if comment_symbols[:multiline]
         | 
| 69 | 
            +
                      begin_symbol = Regexp.escape(comment_symbols[:multiline][:begin])
         | 
| 70 | 
            +
                      end_symbol = Regexp.escape(comment_symbols[:multiline][:end])
         | 
| 71 | 
            +
                      if i < lines.size && lines[i] =~ /\s*#{begin_symbol}/
         | 
| 72 | 
            +
                        begin
         | 
| 73 | 
            +
                          match = lines[i].match /\s*(#{begin_symbol})?\s?(.*?)(#{end_symbol}|$)/
         | 
| 74 | 
            +
                          comment_lines << match[2]
         | 
| 75 | 
            +
                          i += 1
         | 
| 76 | 
            +
                        end while i < lines.size && !(lines[i-1] =~ /\s*#{end_symbol}/)
         | 
| 77 | 
            +
                      end
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                    # getting source lines
         | 
| 81 | 
            +
                    starting_line = i
         | 
| 82 | 
            +
                    source_lines = []
         | 
| 83 | 
            +
                    while i < lines.size && !is_comment.call(lines[i])
         | 
| 84 | 
            +
                      source_lines << lines[i]
         | 
| 85 | 
            +
                      i += 1
         | 
| 86 | 
            +
                    end
         | 
| 87 | 
            +
                    # post-processing: stripping comments and removing empty strings from beginnings and ends
         | 
| 88 | 
            +
                    while source_lines.size > 0 && source_lines[0] =~ /^\s*$/
         | 
| 89 | 
            +
                      starting_line += 1
         | 
| 90 | 
            +
                      source_lines.delete_at(0)
         | 
| 91 | 
            +
                    end
         | 
| 92 | 
            +
                    source_lines.delete_at(-1) while source_lines.size > 0 && source_lines[-1] =~ /^\s*$/
         | 
| 93 | 
            +
                    comment_lines.map! {|l| l.strip }
         | 
| 94 | 
            +
                    comment_lines.delete_at(0) while comment_lines.size > 0 && comment_lines[0].empty?
         | 
| 95 | 
            +
                    comment_lines.delete_at(-1) while comment_lines.size > 0 && comment_lines[-1].empty?
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                    # writing a new paragraph
         | 
| 98 | 
            +
                    @paragraphs << Paragraph.new(source_lines.join("\n"), comment_lines.join("\n"), starting_line, source_type)
         | 
| 99 | 
            +
                  end
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                # Rest of the file quite less self-explanatory
         | 
| 103 | 
            +
                def source
         | 
| 104 | 
            +
                  @source
         | 
| 105 | 
            +
                end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
              protected
         | 
| 108 | 
            +
                def comment_symbols
         | 
| 109 | 
            +
                  super || {}
         | 
| 110 | 
            +
                end
         | 
| 111 | 
            +
              end
         | 
| 112 | 
            +
            end
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            require "haml"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Murdoc
         | 
| 4 | 
            +
              class Formatter
         | 
| 5 | 
            +
                attr_accessor :template
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(template_or_filename)
         | 
| 8 | 
            +
                  if File.exists?(template_or_filename)
         | 
| 9 | 
            +
                    @template = File.read(template_or_filename)
         | 
| 10 | 
            +
                  else
         | 
| 11 | 
            +
                    @template = template_or_filename
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def render(locals = {})
         | 
| 16 | 
            +
                  ::Haml::Engine.new(template).render(self, locals)
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -0,0 +1,43 @@ | |
| 1 | 
            +
            # Javascript language module
         | 
| 2 | 
            +
            module Murdoc
         | 
| 3 | 
            +
              module Languages
         | 
| 4 | 
            +
                module Javascript
         | 
| 5 | 
            +
                  module Annotator
         | 
| 6 | 
            +
                    def self.included(base)
         | 
| 7 | 
            +
                      base.extend ClassMethods
         | 
| 8 | 
            +
                    end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    module ClassMethods
         | 
| 11 | 
            +
                      protected
         | 
| 12 | 
            +
                      def detect_source_type_from_filename(filename)
         | 
| 13 | 
            +
                        if File.extname(filename) == ".js"
         | 
| 14 | 
            +
                          :javascript
         | 
| 15 | 
            +
                        else
         | 
| 16 | 
            +
                          super if defined?(super)
         | 
| 17 | 
            +
                        end
         | 
| 18 | 
            +
                      end
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  module CommentSymbols
         | 
| 23 | 
            +
                    protected
         | 
| 24 | 
            +
                    def comment_symbols
         | 
| 25 | 
            +
                      if source_type == "javascript"
         | 
| 26 | 
            +
                        {:single_line => "//", :multiline => {:begin => "/*", :end => "*/"}}
         | 
| 27 | 
            +
                      else
         | 
| 28 | 
            +
                        super if defined?(super)
         | 
| 29 | 
            +
                      end
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              class Annotator
         | 
| 36 | 
            +
                include Languages::Javascript::Annotator
         | 
| 37 | 
            +
                include Languages::Javascript::CommentSymbols
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              class Paragraph
         | 
| 41 | 
            +
                include Languages::Javascript::CommentSymbols
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
            end
         | 
| @@ -0,0 +1,43 @@ | |
| 1 | 
            +
            # Ruby language module
         | 
| 2 | 
            +
            module Murdoc
         | 
| 3 | 
            +
              module Languages
         | 
| 4 | 
            +
                module Ruby
         | 
| 5 | 
            +
                  module Annotator
         | 
| 6 | 
            +
                    def self.included(base)
         | 
| 7 | 
            +
                      base.extend ClassMethods
         | 
| 8 | 
            +
                    end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    module ClassMethods
         | 
| 11 | 
            +
                      protected
         | 
| 12 | 
            +
                      def detect_source_type_from_filename(filename)
         | 
| 13 | 
            +
                        if File.extname(filename) == ".rb"
         | 
| 14 | 
            +
                          :ruby
         | 
| 15 | 
            +
                        else
         | 
| 16 | 
            +
                          super if defined?(super)
         | 
| 17 | 
            +
                        end
         | 
| 18 | 
            +
                      end
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  module CommentSymbols
         | 
| 23 | 
            +
                    protected
         | 
| 24 | 
            +
                    def comment_symbols
         | 
| 25 | 
            +
                      if source_type == "ruby"
         | 
| 26 | 
            +
                        {:single_line => "#", :multiline => {:begin => "=begin", :end => "=end"}}
         | 
| 27 | 
            +
                      else
         | 
| 28 | 
            +
                        super if defined?(super)
         | 
| 29 | 
            +
                      end
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              class Annotator
         | 
| 36 | 
            +
                include Languages::Ruby::Annotator
         | 
| 37 | 
            +
                include Languages::Ruby::CommentSymbols
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              class Paragraph
         | 
| 41 | 
            +
                include Languages::Ruby::CommentSymbols
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
            end
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            require "rubygems"
         | 
| 2 | 
            +
            require "rdiscount"
         | 
| 3 | 
            +
            require "cgi"
         | 
| 4 | 
            +
            require "tempfile"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module Murdoc
         | 
| 7 | 
            +
              class Paragraph
         | 
| 8 | 
            +
                attr_accessor :source
         | 
| 9 | 
            +
                attr_accessor :annotation
         | 
| 10 | 
            +
                attr_accessor :source_type
         | 
| 11 | 
            +
                attr_accessor :starting_line
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def initialize(source, annotation, starting_line = 0, source_type = nil)
         | 
| 14 | 
            +
                  self.source = source
         | 
| 15 | 
            +
                  self.annotation = annotation
         | 
| 16 | 
            +
                  self.starting_line = starting_line
         | 
| 17 | 
            +
                  self.source_type = source_type
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def source_type
         | 
| 21 | 
            +
                  @source_type
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def source_type=(source_type)
         | 
| 25 | 
            +
                  @source_type = source_type.to_s
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
             | 
| 29 | 
            +
                def formatted_annotation
         | 
| 30 | 
            +
                  Markdown.new(annotation, :smart).to_html
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def formatted_source
         | 
| 34 | 
            +
                  @formatted_source ||= if pygments_installed?
         | 
| 35 | 
            +
                    IO.popen("pygmentize -l #{source_type} -f html", "w+") do |pipe|
         | 
| 36 | 
            +
                      pipe.puts source
         | 
| 37 | 
            +
                      pipe.close_write
         | 
| 38 | 
            +
                      pipe.read
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
                  else
         | 
| 41 | 
            +
                    "<pre>" + CGI.escapeHTML(source) + "</pre>"
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                protected
         | 
| 46 | 
            +
                def pygments_installed?
         | 
| 47 | 
            +
                  @@pygments_installed ||= ENV['PATH'].split(':').any? { |dir| File.exist?("#{dir}/pygmentize") }
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
| @@ -0,0 +1,241 @@ | |
| 1 | 
            +
            html, body {
         | 
| 2 | 
            +
              min-height: 100%; }
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            p, h1, h2, h3, ol, li, ol, ul, dt, dd, dl, body, html {
         | 
| 5 | 
            +
              padding: 0;
         | 
| 6 | 
            +
              margin: 0; }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            body {
         | 
| 9 | 
            +
              width: 45%;
         | 
| 10 | 
            +
              padding-left: 2.5%;
         | 
| 11 | 
            +
              padding-right: 2.5%;
         | 
| 12 | 
            +
              background: #7ba32d;
         | 
| 13 | 
            +
              font-family: Helvetica; }
         | 
| 14 | 
            +
              body:after {
         | 
| 15 | 
            +
                content: ".";
         | 
| 16 | 
            +
                font-size: 0.01em;
         | 
| 17 | 
            +
                line-height: 0.01em;
         | 
| 18 | 
            +
                display: block;
         | 
| 19 | 
            +
                clear: both; }
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            body > * {
         | 
| 22 | 
            +
              padding-left: 6%;
         | 
| 23 | 
            +
              padding-right: 6%; }
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            html {
         | 
| 26 | 
            +
              background: #094201; }
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            header {
         | 
| 29 | 
            +
              background: rgba(255, 255, 255, 0.1);
         | 
| 30 | 
            +
              padding-top: 1em;
         | 
| 31 | 
            +
              display: block; }
         | 
| 32 | 
            +
              header dl {
         | 
| 33 | 
            +
                margin-top: 1.125em;
         | 
| 34 | 
            +
                font-size: 0.75em; }
         | 
| 35 | 
            +
                header dl dt {
         | 
| 36 | 
            +
                  width: 5em;
         | 
| 37 | 
            +
                  font-weight: bold; }
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            p, dl, li {
         | 
| 40 | 
            +
              color: #c4eeff;
         | 
| 41 | 
            +
              font-weight: normal; }
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            a {
         | 
| 44 | 
            +
              color: #a41717; }
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            p {
         | 
| 47 | 
            +
              margin-top: 1.5em; }
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            h1 {
         | 
| 50 | 
            +
              font-size: 2em; }
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            h2 {
         | 
| 53 | 
            +
              font-size: 1em;
         | 
| 54 | 
            +
              line-height: 2em; }
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            h1, h2, h3 {
         | 
| 57 | 
            +
              color: #a41717; }
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            ol, li {
         | 
| 60 | 
            +
              margin-left: 1em; }
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            body > div.paragraph, body > h1, body > h2 {
         | 
| 63 | 
            +
              clear: both; }
         | 
| 64 | 
            +
             | 
| 65 | 
            +
            header {
         | 
| 66 | 
            +
              padding-bottom: 1em;
         | 
| 67 | 
            +
              overflow: hidden; }
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            pre {
         | 
| 70 | 
            +
              margin-top: 0;
         | 
| 71 | 
            +
            }
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            dl {
         | 
| 74 | 
            +
              clear: left; }
         | 
| 75 | 
            +
              dl dt, dl dd {
         | 
| 76 | 
            +
                float: left; }
         | 
| 77 | 
            +
              dl dt {
         | 
| 78 | 
            +
                clear: left; }
         | 
| 79 | 
            +
              dl dd {
         | 
| 80 | 
            +
                margin-left: 1em; }
         | 
| 81 | 
            +
             | 
| 82 | 
            +
            section {
         | 
| 83 | 
            +
                clear: both;
         | 
| 84 | 
            +
            }
         | 
| 85 | 
            +
             | 
| 86 | 
            +
            figure {
         | 
| 87 | 
            +
              display: block;
         | 
| 88 | 
            +
              float: right;
         | 
| 89 | 
            +
              margin-right: -112.5%;
         | 
| 90 | 
            +
              width: 95%;
         | 
| 91 | 
            +
              clear: right;
         | 
| 92 | 
            +
              padding: 2.5em 5% 3em; }
         | 
| 93 | 
            +
              figure > ol {
         | 
| 94 | 
            +
                width: 7.5%;
         | 
| 95 | 
            +
                text-align: right;
         | 
| 96 | 
            +
                float: left;
         | 
| 97 | 
            +
                font-size: 0.8em;
         | 
| 98 | 
            +
                color: #7ba32d;
         | 
| 99 | 
            +
                -webkit-border-radius: 0.2em;
         | 
| 100 | 
            +
                background: rgba(255, 255, 255, 0.1);
         | 
| 101 | 
            +
                border: 1px solid rgba(0, 0, 0, 0.3);
         | 
| 102 | 
            +
                list-style: none;
         | 
| 103 | 
            +
                margin-left: -11.25%; }
         | 
| 104 | 
            +
                figure > ol li {
         | 
| 105 | 
            +
                  margin: 0; }
         | 
| 106 | 
            +
              figure pre {
         | 
| 107 | 
            +
                  background: rgba(255, 255, 255, 0.5);
         | 
| 108 | 
            +
                  border: 1px solid rgba(0, 0, 0, 0.3);
         | 
| 109 | 
            +
                  border-left: none;
         | 
| 110 | 
            +
                  margin-bottom: 0;
         | 
| 111 | 
            +
                  padding-bottom: 0;
         | 
| 112 | 
            +
              }
         | 
| 113 | 
            +
              figure > code, figure > ol {
         | 
| 114 | 
            +
                font-size: 1em;
         | 
| 115 | 
            +
                font-family: monospace; }
         | 
| 116 | 
            +
              figure ~ figure {
         | 
| 117 | 
            +
                padding-top: 1.5em; }
         | 
| 118 | 
            +
             | 
| 119 | 
            +
            body .hll {
         | 
| 120 | 
            +
              background-color: #ffffcc; }
         | 
| 121 | 
            +
            body .c {
         | 
| 122 | 
            +
              color: #408080;
         | 
| 123 | 
            +
              font-style: italic; }
         | 
| 124 | 
            +
            body .err {
         | 
| 125 | 
            +
              border: 1px solid red; }
         | 
| 126 | 
            +
            body .k {
         | 
| 127 | 
            +
              color: #954121; }
         | 
| 128 | 
            +
            body .o {
         | 
| 129 | 
            +
              color: #666666; }
         | 
| 130 | 
            +
            body .cm {
         | 
| 131 | 
            +
              color: #408080;
         | 
| 132 | 
            +
              font-style: italic; }
         | 
| 133 | 
            +
            body .cp {
         | 
| 134 | 
            +
              color: #bc7a00; }
         | 
| 135 | 
            +
            body .c1, body .cs {
         | 
| 136 | 
            +
              color: #408080;
         | 
| 137 | 
            +
              font-style: italic; }
         | 
| 138 | 
            +
            body .gd {
         | 
| 139 | 
            +
              color: #a00000; }
         | 
| 140 | 
            +
            body .ge {
         | 
| 141 | 
            +
              font-style: italic; }
         | 
| 142 | 
            +
            body .gr {
         | 
| 143 | 
            +
              color: red; }
         | 
| 144 | 
            +
            body .gh {
         | 
| 145 | 
            +
              color: navy;
         | 
| 146 | 
            +
              font-weight: bold; }
         | 
| 147 | 
            +
            body .gi {
         | 
| 148 | 
            +
              color: #00a000; }
         | 
| 149 | 
            +
            body .go {
         | 
| 150 | 
            +
              color: gray; }
         | 
| 151 | 
            +
            body .gp {
         | 
| 152 | 
            +
              color: navy;
         | 
| 153 | 
            +
              font-weight: bold; }
         | 
| 154 | 
            +
            body .gs {
         | 
| 155 | 
            +
              font-weight: bold; }
         | 
| 156 | 
            +
            body .gu {
         | 
| 157 | 
            +
              color: purple;
         | 
| 158 | 
            +
              font-weight: bold; }
         | 
| 159 | 
            +
            body .gt {
         | 
| 160 | 
            +
              color: #0040d0; }
         | 
| 161 | 
            +
            body .kc {
         | 
| 162 | 
            +
              color: #954121; }
         | 
| 163 | 
            +
            body .kd, body .kn {
         | 
| 164 | 
            +
              color: #954121;
         | 
| 165 | 
            +
              font-weight: bold; }
         | 
| 166 | 
            +
            body .kp {
         | 
| 167 | 
            +
              color: #954121; }
         | 
| 168 | 
            +
            body .kr {
         | 
| 169 | 
            +
              color: #954121;
         | 
| 170 | 
            +
              font-weight: bold; }
         | 
| 171 | 
            +
            body .kt {
         | 
| 172 | 
            +
              color: #b00040; }
         | 
| 173 | 
            +
            body .m {
         | 
| 174 | 
            +
              color: #666666; }
         | 
| 175 | 
            +
            body .s {
         | 
| 176 | 
            +
              color: #219161; }
         | 
| 177 | 
            +
            body .na {
         | 
| 178 | 
            +
              color: #7d9029; }
         | 
| 179 | 
            +
            body .nb {
         | 
| 180 | 
            +
              color: #954121; }
         | 
| 181 | 
            +
            body .nc {
         | 
| 182 | 
            +
              color: blue;
         | 
| 183 | 
            +
              font-weight: bold; }
         | 
| 184 | 
            +
            body .no {
         | 
| 185 | 
            +
              color: #880000; }
         | 
| 186 | 
            +
            body .nd {
         | 
| 187 | 
            +
              color: #aa22ff; }
         | 
| 188 | 
            +
            body .ni {
         | 
| 189 | 
            +
              color: #999999;
         | 
| 190 | 
            +
              font-weight: bold; }
         | 
| 191 | 
            +
            body .ne {
         | 
| 192 | 
            +
              color: #d2413a;
         | 
| 193 | 
            +
              font-weight: bold; }
         | 
| 194 | 
            +
            body .nf {
         | 
| 195 | 
            +
              color: blue; }
         | 
| 196 | 
            +
            body .nl {
         | 
| 197 | 
            +
              color: #a0a000; }
         | 
| 198 | 
            +
            body .nn {
         | 
| 199 | 
            +
              color: blue;
         | 
| 200 | 
            +
              font-weight: bold; }
         | 
| 201 | 
            +
            body .nt {
         | 
| 202 | 
            +
              color: #954121;
         | 
| 203 | 
            +
              font-weight: bold; }
         | 
| 204 | 
            +
            body .nv {
         | 
| 205 | 
            +
              color: #19469d; }
         | 
| 206 | 
            +
            body .ow {
         | 
| 207 | 
            +
              color: #aa22ff;
         | 
| 208 | 
            +
              font-weight: bold; }
         | 
| 209 | 
            +
            body .w {
         | 
| 210 | 
            +
              color: #bbbbbb; }
         | 
| 211 | 
            +
            body .mf, body .mh, body .mi, body .mo {
         | 
| 212 | 
            +
              color: #666666; }
         | 
| 213 | 
            +
            body .sb, body .sc {
         | 
| 214 | 
            +
              color: #219161; }
         | 
| 215 | 
            +
            body .sd {
         | 
| 216 | 
            +
              color: #219161;
         | 
| 217 | 
            +
              font-style: italic; }
         | 
| 218 | 
            +
            body .s2 {
         | 
| 219 | 
            +
              color: #219161; }
         | 
| 220 | 
            +
            body .se {
         | 
| 221 | 
            +
              color: #bb6622;
         | 
| 222 | 
            +
              font-weight: bold; }
         | 
| 223 | 
            +
            body .sh {
         | 
| 224 | 
            +
              color: #219161; }
         | 
| 225 | 
            +
            body .si {
         | 
| 226 | 
            +
              color: #bb6688;
         | 
| 227 | 
            +
              font-weight: bold; }
         | 
| 228 | 
            +
            body .sx {
         | 
| 229 | 
            +
              color: #954121; }
         | 
| 230 | 
            +
            body .sr {
         | 
| 231 | 
            +
              color: #bb6688; }
         | 
| 232 | 
            +
            body .s1 {
         | 
| 233 | 
            +
              color: #219161; }
         | 
| 234 | 
            +
            body .ss {
         | 
| 235 | 
            +
              color: #19469d; }
         | 
| 236 | 
            +
            body .bp {
         | 
| 237 | 
            +
              color: #954121; }
         | 
| 238 | 
            +
            body .vc, body .vg, body .vi {
         | 
| 239 | 
            +
              color: #19469d; }
         | 
| 240 | 
            +
            body .il {
         | 
| 241 | 
            +
              color: #666666; }
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            !!!
         | 
| 2 | 
            +
            %html
         | 
| 3 | 
            +
              %head
         | 
| 4 | 
            +
                %title Murdoc
         | 
| 5 | 
            +
                %style=stylesheet
         | 
| 6 | 
            +
              %body
         | 
| 7 | 
            +
                - paragraphs.each do |p|
         | 
| 8 | 
            +
                  - unless p.annotation.empty?
         | 
| 9 | 
            +
                    %section= p.formatted_annotation
         | 
| 10 | 
            +
                  - unless p.source.empty?
         | 
| 11 | 
            +
                    %figure
         | 
| 12 | 
            +
                      %ol
         | 
| 13 | 
            +
                        - 1.upto(p.source.split("\n").size) do |i|
         | 
| 14 | 
            +
                          %li= i + p.starting_line
         | 
| 15 | 
            +
                      %code<= p.formatted_source
         | 
    
        data/murdoc.gemspec
    ADDED
    
    | @@ -0,0 +1,88 @@ | |
| 1 | 
            +
            # Generated by jeweler
         | 
| 2 | 
            +
            # DO NOT EDIT THIS FILE DIRECTLY
         | 
| 3 | 
            +
            # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
         | 
| 4 | 
            +
            # -*- encoding: utf-8 -*-
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Gem::Specification.new do |s|
         | 
| 7 | 
            +
              s.name = %q{murdoc}
         | 
| 8 | 
            +
              s.version = "0.1.0"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
         | 
| 11 | 
            +
              s.authors = ["Mark Abramov"]
         | 
| 12 | 
            +
              s.date = %q{2010-11-23}
         | 
| 13 | 
            +
              s.default_executable = %q{murdoc}
         | 
| 14 | 
            +
              s.description = %q{Annotated documentation generator, see README.md for details}
         | 
| 15 | 
            +
              s.email = %q{markizko@gmail.com}
         | 
| 16 | 
            +
              s.executables = ["murdoc"]
         | 
| 17 | 
            +
              s.extra_rdoc_files = [
         | 
| 18 | 
            +
                "README.md"
         | 
| 19 | 
            +
              ]
         | 
| 20 | 
            +
              s.files = [
         | 
| 21 | 
            +
                ".document",
         | 
| 22 | 
            +
                ".rspec",
         | 
| 23 | 
            +
                "Gemfile",
         | 
| 24 | 
            +
                "Gemfile.lock",
         | 
| 25 | 
            +
                "README.md",
         | 
| 26 | 
            +
                "Rakefile",
         | 
| 27 | 
            +
                "UNLICENSE",
         | 
| 28 | 
            +
                "VERSION",
         | 
| 29 | 
            +
                "autotest/discover.rb",
         | 
| 30 | 
            +
                "bin/murdoc",
         | 
| 31 | 
            +
                "lib/murdoc.rb",
         | 
| 32 | 
            +
                "lib/murdoc/annotator.rb",
         | 
| 33 | 
            +
                "lib/murdoc/formatter.rb",
         | 
| 34 | 
            +
                "lib/murdoc/languages/javascript.rb",
         | 
| 35 | 
            +
                "lib/murdoc/languages/ruby.rb",
         | 
| 36 | 
            +
                "lib/murdoc/paragraph.rb",
         | 
| 37 | 
            +
                "markup/stylesheet.css",
         | 
| 38 | 
            +
                "markup/template.haml",
         | 
| 39 | 
            +
                "murdoc.gemspec",
         | 
| 40 | 
            +
                "spec/murdoc/annotator_spec.rb",
         | 
| 41 | 
            +
                "spec/murdoc/formatter_spec.rb",
         | 
| 42 | 
            +
                "spec/murdoc/paragraph_spec.rb",
         | 
| 43 | 
            +
                "spec/spec_helper.rb"
         | 
| 44 | 
            +
              ]
         | 
| 45 | 
            +
              s.homepage = %q{http://github.com/markiz/murdoc}
         | 
| 46 | 
            +
              s.licenses = ["Public Domain"]
         | 
| 47 | 
            +
              s.require_paths = ["lib"]
         | 
| 48 | 
            +
              s.rubygems_version = %q{1.3.7}
         | 
| 49 | 
            +
              s.summary = %q{Annotated documentation generator}
         | 
| 50 | 
            +
              s.test_files = [
         | 
| 51 | 
            +
                "spec/murdoc/annotator_spec.rb",
         | 
| 52 | 
            +
                "spec/murdoc/formatter_spec.rb",
         | 
| 53 | 
            +
                "spec/murdoc/paragraph_spec.rb",
         | 
| 54 | 
            +
                "spec/spec_helper.rb"
         | 
| 55 | 
            +
              ]
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              if s.respond_to? :specification_version then
         | 
| 58 | 
            +
                current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
         | 
| 59 | 
            +
                s.specification_version = 3
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
         | 
| 62 | 
            +
                  s.add_runtime_dependency(%q<jeweler>, [">= 0"])
         | 
| 63 | 
            +
                  s.add_runtime_dependency(%q<rspec>, ["~> 2.1.0"])
         | 
| 64 | 
            +
                  s.add_runtime_dependency(%q<rdiscount>, ["~> 1.6.5"])
         | 
| 65 | 
            +
                  s.add_runtime_dependency(%q<haml>, ["~> 3.0.0"])
         | 
| 66 | 
            +
                  s.add_runtime_dependency(%q<sass>, ["~> 3.1.0"])
         | 
| 67 | 
            +
                  s.add_runtime_dependency(%q<haml>, ["~> 3.0.0"])
         | 
| 68 | 
            +
                  s.add_runtime_dependency(%q<rdiscount>, ["~> 1.6.5"])
         | 
| 69 | 
            +
                else
         | 
| 70 | 
            +
                  s.add_dependency(%q<jeweler>, [">= 0"])
         | 
| 71 | 
            +
                  s.add_dependency(%q<rspec>, ["~> 2.1.0"])
         | 
| 72 | 
            +
                  s.add_dependency(%q<rdiscount>, ["~> 1.6.5"])
         | 
| 73 | 
            +
                  s.add_dependency(%q<haml>, ["~> 3.0.0"])
         | 
| 74 | 
            +
                  s.add_dependency(%q<sass>, ["~> 3.1.0"])
         | 
| 75 | 
            +
                  s.add_dependency(%q<haml>, ["~> 3.0.0"])
         | 
| 76 | 
            +
                  s.add_dependency(%q<rdiscount>, ["~> 1.6.5"])
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
              else
         | 
| 79 | 
            +
                s.add_dependency(%q<jeweler>, [">= 0"])
         | 
| 80 | 
            +
                s.add_dependency(%q<rspec>, ["~> 2.1.0"])
         | 
| 81 | 
            +
                s.add_dependency(%q<rdiscount>, ["~> 1.6.5"])
         | 
| 82 | 
            +
                s.add_dependency(%q<haml>, ["~> 3.0.0"])
         | 
| 83 | 
            +
                s.add_dependency(%q<sass>, ["~> 3.1.0"])
         | 
| 84 | 
            +
                s.add_dependency(%q<haml>, ["~> 3.0.0"])
         | 
| 85 | 
            +
                s.add_dependency(%q<rdiscount>, ["~> 1.6.5"])
         | 
| 86 | 
            +
              end
         | 
| 87 | 
            +
            end
         | 
| 88 | 
            +
             | 
| @@ -0,0 +1,111 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
            require "fileutils"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe Murdoc::Annotator do
         | 
| 5 | 
            +
              describe "#initialize" do
         | 
| 6 | 
            +
                it "should set #source from source text" do
         | 
| 7 | 
            +
                  Murdoc::Annotator.new("Procrastination", "plaintext").source.should == "Procrastination"
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                it "should set source type from second argument" do
         | 
| 11 | 
            +
                  Murdoc::Annotator.new("# Hello", "ruby").source_type.should == "ruby"
         | 
| 12 | 
            +
                  Murdoc::Annotator.new("# Hello", :ruby).source_type.should == "ruby"
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              describe ".from_file" do
         | 
| 17 | 
            +
                after(:each) { FileUtils.rm "annotator_test.rb", :force => true }
         | 
| 18 | 
            +
                it "should set #source from file contents" do
         | 
| 19 | 
            +
                  File.open("annotator_test.rb", "w+") do |f|
         | 
| 20 | 
            +
                    f.puts "# Comment"
         | 
| 21 | 
            +
                    f.puts "puts 'Hello, world!'"
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  described_class.from_file("annotator_test.rb").source.should =~ /# Comment\s+puts 'Hello, world!'/
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                it "should detect source type from extension" do
         | 
| 28 | 
            +
                  File.open("annotator_test.rb", "w+")
         | 
| 29 | 
            +
                  described_class.stub!(:detect_source_type_from_filename).and_return("test")
         | 
| 30 | 
            +
                  described_class.from_file("annotator_test.rb").source_type.should == "test"
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                it "should still let me force source type" do
         | 
| 34 | 
            +
                  File.open("annotator_test.rb", "w+")      
         | 
| 35 | 
            +
                  described_class.from_file("annotator_test.rb", "code").source_type.should == "code"
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
             | 
| 40 | 
            +
              describe "#source=" do
         | 
| 41 | 
            +
                let(:source) { "" }
         | 
| 42 | 
            +
                subject { described_class.new(source, :ruby) }
         | 
| 43 | 
            +
                context "for source with single-line comments" do
         | 
| 44 | 
            +
                  let(:source) { "# Block one\n# Block one!!!!\n     def hi\nputs 'hello'\nend\n\n# Block two\ndef yo\nputs 'rap'\nend\n" }
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  it "should split source into paragraphs" do
         | 
| 47 | 
            +
                    subject.should have_exactly(2).paragraphs
         | 
| 48 | 
            +
                    subject.paragraphs[0].source.should =~ /\A\s*def hi\s*puts 'hello'\s*end\s*\Z/m
         | 
| 49 | 
            +
                    subject.paragraphs[0].annotation.should =~ /\ABlock one\s*Block one!!!!\Z/m
         | 
| 50 | 
            +
                    subject.paragraphs[1].source.should =~ /\A\s*def yo\s*puts 'rap'\s*end\s*\Z/m
         | 
| 51 | 
            +
                    subject.paragraphs[1].annotation.should =~ /\ABlock two\Z/m
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  it "should remove trailing comment blank line" do
         | 
| 55 | 
            +
                    subject.source = "# Hello\n#      \n   \n\n"
         | 
| 56 | 
            +
                    subject.should have_exactly(1).paragraphs
         | 
| 57 | 
            +
                    subject.paragraphs[0].annotation.should == "Hello"
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                context "for source with multi-line comments" do
         | 
| 62 | 
            +
                  let(:source) { "=begin\n Block one\n Block one!!!!\n=end\n     def hi\nputs 'hello'\nend\n=begin\nBlock two\n=end\ndef yo\nputs 'rap'\nend\n" }
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  it "should split source into paragraphs" do
         | 
| 65 | 
            +
                    subject.should have_exactly(2).paragraphs
         | 
| 66 | 
            +
                    subject.paragraphs[0].source.should =~ /\A\s*def hi\s*puts 'hello'\s*end\s*\Z/m
         | 
| 67 | 
            +
                    subject.paragraphs[0].annotation.should =~ /\ABlock one\s*Block one!!!!\Z/m
         | 
| 68 | 
            +
                    subject.paragraphs[1].source.should =~ /\A\s*def yo\s*puts 'rap'\s*end\s*\Z/m
         | 
| 69 | 
            +
                    subject.paragraphs[1].annotation.should =~ /\ABlock two\Z/m
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                context "for comment without code" do
         | 
| 74 | 
            +
                  let(:source) { "# Header\n\n\n# Comment\ndef body\nend" }
         | 
| 75 | 
            +
                  it "should create a separate paragraph" do
         | 
| 76 | 
            +
                    subject.should have_exactly(2).paragraphs
         | 
| 77 | 
            +
                    subject.paragraphs[0].source.should == ""
         | 
| 78 | 
            +
                    subject.paragraphs[0].annotation.should == "Header"
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                it "should not choke on edge cases" do
         | 
| 83 | 
            +
                  subject.source = ""
         | 
| 84 | 
            +
                  subject.source = "#"
         | 
| 85 | 
            +
                  subject.source = "# A\n#"
         | 
| 86 | 
            +
                  subject.source = "           # A\n             #            "
         | 
| 87 | 
            +
                  subject.source = "# A\n=begin\n"
         | 
| 88 | 
            +
                  subject.source = "# A\n=begin\n\n          =end yo"
         | 
| 89 | 
            +
                  subject.source = "# A\n=begin\n\n      asdasd    =end yo"
         | 
| 90 | 
            +
                  subject.source = "# A\n=begin\n\n      !!$$    =end yo"
         | 
| 91 | 
            +
                  subject.source = "\n            =begin\n\n          =end yo"
         | 
| 92 | 
            +
                  subject.source = "=begin YO =end\n\n\n\n asdasd asd"
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                it "should remove totally empty source" do
         | 
| 96 | 
            +
                  subject.source = "# Comment\n\n\n\n"
         | 
| 97 | 
            +
                  subject.paragraphs[0].source.should be_empty
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                it "should remove semi-empty lines" do
         | 
| 101 | 
            +
                  subject.source = "def hi\n\nend"
         | 
| 102 | 
            +
                  subject.paragraphs[0].source.should == "def hi\n\nend"
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
              end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
             | 
| 107 | 
            +
              describe "#annotated" do
         | 
| 108 | 
            +
                let(:source) { "# this" }
         | 
| 109 | 
            +
                subject { described_class.new(source, :ruby) }
         | 
| 110 | 
            +
              end
         | 
| 111 | 
            +
            end
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
            require "tempfile"
         | 
| 3 | 
            +
            describe Murdoc::Formatter do
         | 
| 4 | 
            +
              describe "#initialize" do
         | 
| 5 | 
            +
                it "should set template from given string" do
         | 
| 6 | 
            +
                  described_class.new("%p Hello").template.should == "%p Hello"
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                it "should set template from given filename if that filename exists" do
         | 
| 10 | 
            +
                  Tempfile.open("test") do |f|
         | 
| 11 | 
            +
                    f.puts("%p Hello")
         | 
| 12 | 
            +
                    f.close
         | 
| 13 | 
            +
                    described_class.new(f.path).template.should == "%p Hello\n"
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              describe "#render" do
         | 
| 19 | 
            +
                it "should render with haml" do
         | 
| 20 | 
            +
                  described_class.new("%p Hello").render.should =~ %r{<p>Hello</p>}
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
                
         | 
| 23 | 
            +
                it "should send locals to haml" do
         | 
| 24 | 
            +
                  described_class.new("%p= foo").render(:foo => 123).should =~ %r{<p>123</p>}
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Murdoc::Paragraph do
         | 
| 4 | 
            +
              describe "#initialize" do
         | 
| 5 | 
            +
                it "should set source" do
         | 
| 6 | 
            +
                  described_class.new("A", "").source.should == "A"
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                it "should set annotation" do
         | 
| 10 | 
            +
                  described_class.new("", "B").annotation.should == "B"
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                it "should optionally set source_type" do
         | 
| 14 | 
            +
                  described_class.new("", "", 0, :ruby).source_type.should == "ruby"
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                it "should optionally set starting line" do
         | 
| 18 | 
            +
                  described_class.new("", "", 666, :ruby).starting_line.should == 666
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    ADDED
    
    
    
        metadata
    ADDED
    
    | @@ -0,0 +1,192 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification 
         | 
| 2 | 
            +
            name: murdoc
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            +
              prerelease: false
         | 
| 5 | 
            +
              segments: 
         | 
| 6 | 
            +
              - 0
         | 
| 7 | 
            +
              - 1
         | 
| 8 | 
            +
              - 0
         | 
| 9 | 
            +
              version: 0.1.0
         | 
| 10 | 
            +
            platform: ruby
         | 
| 11 | 
            +
            authors: 
         | 
| 12 | 
            +
            - Mark Abramov
         | 
| 13 | 
            +
            autorequire: 
         | 
| 14 | 
            +
            bindir: bin
         | 
| 15 | 
            +
            cert_chain: []
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            date: 2010-11-23 00:00:00 +03:00
         | 
| 18 | 
            +
            default_executable: murdoc
         | 
| 19 | 
            +
            dependencies: 
         | 
| 20 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 21 | 
            +
              name: jeweler
         | 
| 22 | 
            +
              requirement: &id001 !ruby/object:Gem::Requirement 
         | 
| 23 | 
            +
                none: false
         | 
| 24 | 
            +
                requirements: 
         | 
| 25 | 
            +
                - - ">="
         | 
| 26 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 27 | 
            +
                    segments: 
         | 
| 28 | 
            +
                    - 0
         | 
| 29 | 
            +
                    version: "0"
         | 
| 30 | 
            +
              type: :runtime
         | 
| 31 | 
            +
              prerelease: false
         | 
| 32 | 
            +
              version_requirements: *id001
         | 
| 33 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 34 | 
            +
              name: rspec
         | 
| 35 | 
            +
              requirement: &id002 !ruby/object:Gem::Requirement 
         | 
| 36 | 
            +
                none: false
         | 
| 37 | 
            +
                requirements: 
         | 
| 38 | 
            +
                - - ~>
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 40 | 
            +
                    segments: 
         | 
| 41 | 
            +
                    - 2
         | 
| 42 | 
            +
                    - 1
         | 
| 43 | 
            +
                    - 0
         | 
| 44 | 
            +
                    version: 2.1.0
         | 
| 45 | 
            +
              type: :runtime
         | 
| 46 | 
            +
              prerelease: false
         | 
| 47 | 
            +
              version_requirements: *id002
         | 
| 48 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 49 | 
            +
              name: rdiscount
         | 
| 50 | 
            +
              requirement: &id003 !ruby/object:Gem::Requirement 
         | 
| 51 | 
            +
                none: false
         | 
| 52 | 
            +
                requirements: 
         | 
| 53 | 
            +
                - - ~>
         | 
| 54 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 55 | 
            +
                    segments: 
         | 
| 56 | 
            +
                    - 1
         | 
| 57 | 
            +
                    - 6
         | 
| 58 | 
            +
                    - 5
         | 
| 59 | 
            +
                    version: 1.6.5
         | 
| 60 | 
            +
              type: :runtime
         | 
| 61 | 
            +
              prerelease: false
         | 
| 62 | 
            +
              version_requirements: *id003
         | 
| 63 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 64 | 
            +
              name: haml
         | 
| 65 | 
            +
              requirement: &id004 !ruby/object:Gem::Requirement 
         | 
| 66 | 
            +
                none: false
         | 
| 67 | 
            +
                requirements: 
         | 
| 68 | 
            +
                - - ~>
         | 
| 69 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 70 | 
            +
                    segments: 
         | 
| 71 | 
            +
                    - 3
         | 
| 72 | 
            +
                    - 0
         | 
| 73 | 
            +
                    - 0
         | 
| 74 | 
            +
                    version: 3.0.0
         | 
| 75 | 
            +
              type: :runtime
         | 
| 76 | 
            +
              prerelease: false
         | 
| 77 | 
            +
              version_requirements: *id004
         | 
| 78 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 79 | 
            +
              name: sass
         | 
| 80 | 
            +
              requirement: &id005 !ruby/object:Gem::Requirement 
         | 
| 81 | 
            +
                none: false
         | 
| 82 | 
            +
                requirements: 
         | 
| 83 | 
            +
                - - ~>
         | 
| 84 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 85 | 
            +
                    segments: 
         | 
| 86 | 
            +
                    - 3
         | 
| 87 | 
            +
                    - 1
         | 
| 88 | 
            +
                    - 0
         | 
| 89 | 
            +
                    version: 3.1.0
         | 
| 90 | 
            +
              type: :runtime
         | 
| 91 | 
            +
              prerelease: false
         | 
| 92 | 
            +
              version_requirements: *id005
         | 
| 93 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 94 | 
            +
              name: haml
         | 
| 95 | 
            +
              requirement: &id006 !ruby/object:Gem::Requirement 
         | 
| 96 | 
            +
                none: false
         | 
| 97 | 
            +
                requirements: 
         | 
| 98 | 
            +
                - - ~>
         | 
| 99 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 100 | 
            +
                    segments: 
         | 
| 101 | 
            +
                    - 3
         | 
| 102 | 
            +
                    - 0
         | 
| 103 | 
            +
                    - 0
         | 
| 104 | 
            +
                    version: 3.0.0
         | 
| 105 | 
            +
              type: :runtime
         | 
| 106 | 
            +
              prerelease: false
         | 
| 107 | 
            +
              version_requirements: *id006
         | 
| 108 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 109 | 
            +
              name: rdiscount
         | 
| 110 | 
            +
              requirement: &id007 !ruby/object:Gem::Requirement 
         | 
| 111 | 
            +
                none: false
         | 
| 112 | 
            +
                requirements: 
         | 
| 113 | 
            +
                - - ~>
         | 
| 114 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 115 | 
            +
                    segments: 
         | 
| 116 | 
            +
                    - 1
         | 
| 117 | 
            +
                    - 6
         | 
| 118 | 
            +
                    - 5
         | 
| 119 | 
            +
                    version: 1.6.5
         | 
| 120 | 
            +
              type: :runtime
         | 
| 121 | 
            +
              prerelease: false
         | 
| 122 | 
            +
              version_requirements: *id007
         | 
| 123 | 
            +
            description: Annotated documentation generator, see README.md for details
         | 
| 124 | 
            +
            email: markizko@gmail.com
         | 
| 125 | 
            +
            executables: 
         | 
| 126 | 
            +
            - murdoc
         | 
| 127 | 
            +
            extensions: []
         | 
| 128 | 
            +
             | 
| 129 | 
            +
            extra_rdoc_files: 
         | 
| 130 | 
            +
            - README.md
         | 
| 131 | 
            +
            files: 
         | 
| 132 | 
            +
            - .document
         | 
| 133 | 
            +
            - .rspec
         | 
| 134 | 
            +
            - Gemfile
         | 
| 135 | 
            +
            - Gemfile.lock
         | 
| 136 | 
            +
            - README.md
         | 
| 137 | 
            +
            - Rakefile
         | 
| 138 | 
            +
            - UNLICENSE
         | 
| 139 | 
            +
            - VERSION
         | 
| 140 | 
            +
            - autotest/discover.rb
         | 
| 141 | 
            +
            - bin/murdoc
         | 
| 142 | 
            +
            - lib/murdoc.rb
         | 
| 143 | 
            +
            - lib/murdoc/annotator.rb
         | 
| 144 | 
            +
            - lib/murdoc/formatter.rb
         | 
| 145 | 
            +
            - lib/murdoc/languages/javascript.rb
         | 
| 146 | 
            +
            - lib/murdoc/languages/ruby.rb
         | 
| 147 | 
            +
            - lib/murdoc/paragraph.rb
         | 
| 148 | 
            +
            - markup/stylesheet.css
         | 
| 149 | 
            +
            - markup/template.haml
         | 
| 150 | 
            +
            - murdoc.gemspec
         | 
| 151 | 
            +
            - spec/murdoc/annotator_spec.rb
         | 
| 152 | 
            +
            - spec/murdoc/formatter_spec.rb
         | 
| 153 | 
            +
            - spec/murdoc/paragraph_spec.rb
         | 
| 154 | 
            +
            - spec/spec_helper.rb
         | 
| 155 | 
            +
            has_rdoc: true
         | 
| 156 | 
            +
            homepage: http://github.com/markiz/murdoc
         | 
| 157 | 
            +
            licenses: 
         | 
| 158 | 
            +
            - Public Domain
         | 
| 159 | 
            +
            post_install_message: 
         | 
| 160 | 
            +
            rdoc_options: []
         | 
| 161 | 
            +
             | 
| 162 | 
            +
            require_paths: 
         | 
| 163 | 
            +
            - lib
         | 
| 164 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         | 
| 165 | 
            +
              none: false
         | 
| 166 | 
            +
              requirements: 
         | 
| 167 | 
            +
              - - ">="
         | 
| 168 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 169 | 
            +
                  hash: 303347797677614350
         | 
| 170 | 
            +
                  segments: 
         | 
| 171 | 
            +
                  - 0
         | 
| 172 | 
            +
                  version: "0"
         | 
| 173 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         | 
| 174 | 
            +
              none: false
         | 
| 175 | 
            +
              requirements: 
         | 
| 176 | 
            +
              - - ">="
         | 
| 177 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 178 | 
            +
                  segments: 
         | 
| 179 | 
            +
                  - 0
         | 
| 180 | 
            +
                  version: "0"
         | 
| 181 | 
            +
            requirements: []
         | 
| 182 | 
            +
             | 
| 183 | 
            +
            rubyforge_project: 
         | 
| 184 | 
            +
            rubygems_version: 1.3.7
         | 
| 185 | 
            +
            signing_key: 
         | 
| 186 | 
            +
            specification_version: 3
         | 
| 187 | 
            +
            summary: Annotated documentation generator
         | 
| 188 | 
            +
            test_files: 
         | 
| 189 | 
            +
            - spec/murdoc/annotator_spec.rb
         | 
| 190 | 
            +
            - spec/murdoc/formatter_spec.rb
         | 
| 191 | 
            +
            - spec/murdoc/paragraph_spec.rb
         | 
| 192 | 
            +
            - spec/spec_helper.rb
         |