Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first commit

  • Loading branch information...
commit 32e8b2075dfd310c3ae6c20ac393764afe644fdd 0 parents
@txus txus authored
3  .gitignore
@@ -0,0 +1,3 @@
+pkg/*
+*.gem
+.bundle
2  .rspec
@@ -0,0 +1,2 @@
+--color
+--format documentation
1  .rvmrc
@@ -0,0 +1 @@
+rvm --create use ruby-1.9.2@markdownizer
4 Gemfile
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in markdownizer.gemspec
+gemspec
46 Gemfile.lock
@@ -0,0 +1,46 @@
+PATH
+ remote: .
+ specs:
+ markdownizer (0.0.1)
+ activerecord (~> 3.0.3)
+ coderay
+ rdiscount
+
+GEM
+ remote: http://rubygems.org/
+ specs:
+ activemodel (3.0.3)
+ activesupport (= 3.0.3)
+ builder (~> 2.1.2)
+ i18n (~> 0.4)
+ activerecord (3.0.3)
+ activemodel (= 3.0.3)
+ activesupport (= 3.0.3)
+ arel (~> 2.0.2)
+ tzinfo (~> 0.3.23)
+ activesupport (3.0.3)
+ arel (2.0.7)
+ builder (2.1.2)
+ coderay (0.9.7)
+ diff-lcs (1.1.2)
+ i18n (0.5.0)
+ rdiscount (1.6.8)
+ rspec (2.4.0)
+ rspec-core (~> 2.4.0)
+ rspec-expectations (~> 2.4.0)
+ rspec-mocks (~> 2.4.0)
+ rspec-core (2.4.0)
+ rspec-expectations (2.4.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.4.0)
+ tzinfo (0.3.24)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ activerecord (~> 3.0.3)
+ coderay
+ markdownizer!
+ rdiscount
+ rspec (~> 2.4.0)
10 Rakefile
@@ -0,0 +1,10 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
+
+require 'rspec/core'
+require 'rspec/core/rake_task'
+RSpec::Core::RakeTask.new(:spec) do |spec|
+ spec.pattern = FileList['spec/**/*_spec.rb']
+end
+
+task :default => :spec
59 Readme.md
@@ -0,0 +1,59 @@
+#Markdownizer
+
+A simple gem for Rails 3 to render some ActiveRecord text field as Markdown!
+
+It mixes CodeRay and RDiscount to give you awesome code highlighting :)
+
+##Install
+
+In your Gemfile:
+
+ gem 'markdownizer'
+
+## Usage
+
+In your model, let's say, Post:
+
+ class Post < ActiveRecord::Base
+ markdownize! :body # In this case we want to treat :body as markdown
+ end
+
+Markdownizer needs an additional field (`:rendered_body`), which you should
+generate in a migration. (If the attribute was `:some_other_field`, it would need
+`:rendered_some_other_field`!) All these fields should have the type `:text`.
+
+You save your posts with markdown text like this:
+
+ Post.create body: """
+ # My H1 title
+ Markdown is awesome!
+ ## Some H2 title...
+
+ {% highlight ruby %}
+
+ # All this code will be highlighted properly! :)
+ def my_method(*my_args)
+ something do
+ . . .
+ end
+ end
+
+ {% endhighlight %}
+ """
+
+And then, in your view you just have to call `@post.rendered_body` :)
+
+##Contribute!
+
+* Fork the project.
+* Make your feature addition or bug fix.
+* Add specs for it. This is important so I don't break it in a future
+ version unintentionally.
+* Commit, do not mess with rakefile, version, or history.
+ If you want to have your own version, that is fine but bump version
+ in a commit by itself I can ignore when I pull.
+* Send me a pull request. Bonus points for topic branches.
+
+## Copyright
+
+Copyright (c) 2011 Codegram. See LICENSE for details.
35 lib/markdownizer.rb
@@ -0,0 +1,35 @@
+require 'rdiscount'
+require 'coderay'
+require 'active_record' unless defined?(ActiveRecord)
+
+module Markdownizer
+
+ class << self
+ def markdown(text)
+ RDiscount.new(text).to_html
+ end
+
+ def coderay(text)
+ text.gsub(%r[\{% highlight (\w+?) %\}(.+?)\{% endhighlight %\}]m) do
+ CodeRay.scan($2, $1).div(:css => :class)
+ end
+ end
+ end
+
+ module DSL
+ def markdownize! attribute
+ unless self.column_names.include?(attribute.to_s) &&
+ self.column_names.include?("rendered_#{attribute}")
+ raise "#{self.name} doesn't have required attributes :#{attribute} and :rendered_#{attribute}\nPlease generate a migration to add these attributes -- both should have type :text."
+ end
+ self.before_save :"render_#{attribute}"
+
+ define_method :"render_#{attribute}" do
+ self.send(:"rendered_#{attribute}=", Markdownizer.markdown(Markdownizer.coderay(self.send(attribute))))
+ end
+ end
+ end
+
+end
+
+ActiveRecord::Base.send(:extend, Markdownizer::DSL)
3  lib/markdownizer/version.rb
@@ -0,0 +1,3 @@
+module Markdownizer
+ VERSION = "0.0.1"
+end
27 markdownizer.gemspec
@@ -0,0 +1,27 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "markdownizer/version"
+
+Gem::Specification.new do |s|
+ s.name = "markdownizer"
+ s.version = Markdownizer::VERSION
+ s.platform = Gem::Platform::RUBY
+ s.authors = ["Josep M. Bach", "Josep Jaume Rey", "Oriol Gual"]
+ s.email = ["info@codegram.com"]
+ s.homepage = "http://github.com/codegram/markdownizer"
+ s.summary = %q{Render any text as markdown, with code highlighting and all!}
+ s.description = %q{Render any text as markdown, with code highlighting and all!}
+
+ s.rubyforge_project = "markdownizer"
+
+ s.add_runtime_dependency 'activerecord', '~> 3.0.3'
+ s.add_runtime_dependency 'rdiscount'
+ s.add_runtime_dependency 'coderay'
+
+ s.add_development_dependency 'rspec', '~> 2.4.0'
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ["lib"]
+end
92 spec/markdownizer_spec.rb
@@ -0,0 +1,92 @@
+require 'spec_helper'
+
+describe Markdownizer do
+ describe ".markdown(text)" do
+ let(:text) { "#My markdown text"}
+ it 'calls RDiscount to markdownize the text' do
+ rdiscount, html_markdown = double(:rdiscount), double(:html_markdown)
+
+ RDiscount.should_receive(:new).with(text).and_return rdiscount
+ rdiscount.should_receive(:to_html).and_return html_markdown
+
+ subject.markdown(text).should == html_markdown
+ end
+ end
+ describe ".coderay(text)" do
+ let(:text) { """
+ #My markdown text
+
+ {% highlight ruby %}
+ def function(*args)
+ puts 'result'
+ end
+ {% endhighlight %}
+
+ """
+ }
+ it 'calls CodeRay to parse the code inside {% highlight ruby %} blocks' do
+ scanned_code, html_code = double(:scanned_code), double(:html_code)
+
+ CodeRay.should_receive(:scan).with("""
+ def function(*args)
+ puts 'result'
+ end
+ """, 'ruby').and_return scanned_code
+
+ scanned_code.should_receive(:div).with(:css => :class).and_return 'parsed code'
+
+ subject.coderay(text).should match('parsed code')
+ end
+ end
+
+ describe Markdownizer::DSL do
+ it 'integrates with ActiveRecord::Base' do
+ (class << ActiveRecord::Base; self; end).ancestors.should include(Markdownizer::DSL)
+ end
+
+ before do
+ ActiveRecord::Base.stub(:send)
+ @klass = Class.new(ActiveRecord::Base)
+ @klass.stub(:column_names) { %{body rendered_body} }
+ end
+
+ describe "#markdownize!(attribute)" do
+ context "when either of attribute or rendered_attribute does not exist" do
+ it 'raises' do
+ expect {
+ @klass.markdownize! :some_attribute
+ }.to raise_error
+ end
+ end
+ context "otherwise" do
+ it 'creates a before_save callback for render_attribute' do
+ @klass.should_receive(:before_save).with(:render_body)
+ @klass.markdownize! :body
+ end
+ it 'defines this render_attribute method' do
+ klass = Class.new do
+ extend Markdownizer::DSL
+ def self.column_names
+ %{body rendered_body}
+ end
+ end
+
+ klass.stub(:before_save)
+ klass.markdownize! :body
+
+ raw_body, raw_body_with_code, final_code = double(:raw_body),
+ double(:raw_body_with_code),
+ double(:final_code)
+
+ instance = klass.new
+ instance.should_receive(:send).with(:body).and_return raw_body
+ Markdownizer.should_receive(:coderay).with(raw_body).and_return raw_body_with_code
+ Markdownizer.should_receive(:markdown).with(raw_body_with_code).and_return final_code
+
+ instance.should_receive(:send).with(:rendered_body=, final_code)
+ instance.render_body
+ end
+ end
+ end
+ end
+end
2  spec/spec_helper.rb
@@ -0,0 +1,2 @@
+require 'rspec'
+require 'markdownizer'
Please sign in to comment.
Something went wrong with that request. Please try again.