literate_ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.infinity_test ADDED
@@ -0,0 +1,11 @@
1
+ infinity_test do
2
+ use :rubies => %w(ruby-1.9.2 ruby-1.8.7), :app_framework => :rubygems, :verbose => true
3
+
4
+ notifications :growl do
5
+ show_images :mode => :fuuu
6
+ end
7
+
8
+ before_run do
9
+ clear :terminal
10
+ end
11
+ end
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in literate_ruby.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'pry_debug'
8
+ gem 'method_source'
9
+ gem 'minitest'
10
+ gem 'wrong'
11
+ gem 'infinity_test'
12
+ end
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2011 by Andrew O'Brien <obrien.andrew@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,73 @@
1
+ h1. Literate Ruby
2
+
3
+ This library is the first step towards a more literate Ruby syntax, similar to Haskell's (admittedly semi-literate syntax).
4
+
5
+ Applications include: documentation files where there's more text than code (e.g. like READMEs!), blog entries, or a minimalist story runnner.
6
+
7
+ h2. Usage
8
+
9
+ h3. Single lines code
10
+
11
+ <pre><code>
12
+ > puts "This is inline code."
13
+ > puts "But this will be part of the same code block."
14
+ </code></pre>
15
+
16
+ h3. Block code
17
+
18
+ <pre><code>
19
+ =begin_code
20
+ def describe_block_code
21
+ puts "This will all be part of the same code block."
22
+ end
23
+
24
+ describe_block_code
25
+ =end_code
26
+ </code></pre>
27
+
28
+ h3. Loading
29
+
30
+ <pre><code>
31
+ =begin_code
32
+ require 'pp'
33
+ require './lib/literate_ruby'
34
+
35
+ lines = LiterateRuby.load("test/fixtures/fixture.lrb")
36
+
37
+ pp lines
38
+
39
+ pp "FOO: #{FOO}"
40
+ pp "foo (method): #{foo()}"
41
+ =end_code
42
+ </code></pre>
43
+
44
+ h3. Parsing
45
+
46
+ If you just want access to the raw tree without eval'ing the code, do this:
47
+
48
+ <pre><code>
49
+ =begin_code
50
+ require 'pp'
51
+ require './lib/literate_ruby'
52
+
53
+ lines = LiterateRuby.parse(File.new("test/fixtures/fixture.lrb"))
54
+
55
+ pp lines
56
+
57
+ =end_code
58
+ </code></pre>
59
+
60
+ h2. This file is like, so self-referential, or whatever
61
+
62
+ Aim your shells thusly for great justice:
63
+
64
+ <pre><code>
65
+ $ ruby -r./lib/literate_ruby -e "LiterateRuby.load('README.textile')"
66
+ </code></pre>
67
+
68
+ (from this directory)
69
+
70
+ h2. TODOS
71
+
72
+ * Figure out if we need/how best to finish off the LiterateRuby.require method. So someone could write library code if they so desired.
73
+ * Possibly change or make the inline & block delimiters configurable to support different markdown languages' code syntax.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,124 @@
1
+ module LiterateRuby
2
+ # See comment in the test file
3
+ # def self.require(path)
4
+ # full_path = path + ".lrb"
5
+ # if $".include?(full_path)
6
+ # false
7
+ # else
8
+ # if load(full_path)
9
+ # $" << full_path
10
+ # else
11
+ # raise LoadError
12
+ # end
13
+ # end
14
+ # end
15
+
16
+ def self.load(path)
17
+ lines = parse(File.new(path))
18
+
19
+ lines.find_all {|(type, line_group)| type == :code && !line_group.empty?}.each do |(_, line_group)|
20
+ Kernel.eval(
21
+ line_group.map {|(line_no, line)| line}.join(""),
22
+ TOPLEVEL_BINDING,
23
+ path,
24
+ line_group[0][0]
25
+ )
26
+ end
27
+
28
+ lines
29
+ end
30
+
31
+ def self.parse(io)
32
+ state = :open
33
+ lines = []
34
+ buffer = nil
35
+
36
+ io.readlines.each_with_index do |line, i|
37
+ case line
38
+ when /^>/
39
+ clean_line = line.sub(/^>/, "")
40
+ case state
41
+ when :open
42
+ state = :in_code
43
+ buffer = []
44
+ buffer << [i + 1, clean_line]
45
+ when :in_code
46
+ buffer << [i + 1, clean_line]
47
+ when :in_code_block
48
+ buffer << [i + 1, clean_line]
49
+ when :in_data
50
+ lines << [:data, buffer]
51
+ buffer = []
52
+
53
+ state = :in_code
54
+ buffer << [i + 1, clean_line]
55
+ end
56
+ when /^=begin_code/
57
+ case state
58
+ when :open
59
+ buffer = []
60
+ when :in_code
61
+ lines << [:code, buffer]
62
+ buffer = []
63
+ when :in_code_block
64
+ buffer << [i + 1, line]
65
+ when :in_data
66
+ lines << [:data, buffer]
67
+ buffer = []
68
+ end
69
+ state = :in_code_block
70
+ when /^=end_code/
71
+ case state
72
+ when :open
73
+ buffer = []
74
+ state = :in_data
75
+ when :in_code
76
+ lines << [:code, buffer]
77
+ buffer = []
78
+
79
+ state = :in_data
80
+ when :in_code_block
81
+ lines << [:code, buffer]
82
+ buffer = []
83
+
84
+ state = :in_data
85
+ when :in_data
86
+ # no-op
87
+ end
88
+ else
89
+ case state
90
+ when :open
91
+ buffer = []
92
+ state = :in_data
93
+ buffer << [i + 1, line]
94
+ when :in_code
95
+ lines << [:code, buffer]
96
+ buffer = []
97
+
98
+ state = :in_data
99
+ buffer << [i + 1, line]
100
+ when :in_code_block
101
+ buffer << [i + 1, line]
102
+ when :in_data
103
+ buffer << [i + 1, line]
104
+ end
105
+ end
106
+ end
107
+
108
+ case state
109
+ when :open
110
+ # no-op
111
+ when :in_code
112
+ lines << [:code, buffer] unless buffer.empty?
113
+ buffer = nil
114
+ when :in_code_block
115
+ lines << [:code, buffer] unless buffer.empty?
116
+ buffer = nil
117
+ when :in_data
118
+ lines << [:data, buffer] unless buffer.empty?
119
+ buffer = nil
120
+ end
121
+
122
+ lines
123
+ end
124
+ end
@@ -0,0 +1,3 @@
1
+ module LiterateRuby
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "literate_ruby/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "literate_ruby"
7
+ s.version = LiterateRuby::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Andrew O'Brien"]
10
+ s.email = ["obrien.andrew@gmail.com"]
11
+ s.homepage = "http://github.com/AndrewO/literate_ruby"
12
+ s.summary = %q{Don't comment your code. Code your comments.}
13
+ s.description = %q{Literate Ruby is a small preprocessor that allows embedding code within text files and then loading them as programs.}
14
+
15
+ s.rubyforge_project = "literate_ruby"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,15 @@
1
+ FOO is declared to be 123
2
+ Let's test multines
3
+
4
+ And paragraph breaks
5
+ > FOO = 123
6
+ > def foo
7
+ > 1 + 1
8
+ > end
9
+
10
+ BAR is 456
11
+
12
+ =begin_code
13
+ BAR =
14
+ 456
15
+ =end_code
@@ -0,0 +1,10 @@
1
+ BAZ is 678
2
+
3
+ =begin_code
4
+ BAZ =
5
+ 678
6
+ =end_code
7
+
8
+ > def bar
9
+ > 45 + 35
10
+ > end
@@ -0,0 +1,79 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.require(:default, :test)
4
+
5
+ require 'minitest/spec'
6
+ require 'minitest/autorun'
7
+
8
+ require 'wrong/adapters/minitest'
9
+
10
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
11
+ require "literate_ruby"
12
+
13
+ FIXTURE_DIR = File.join(File.dirname(__FILE__), "fixtures")
14
+
15
+ describe LiterateRuby do
16
+ it "parses literate ruby files returning annotated lines" do
17
+ lines = LiterateRuby.parse(File.new(File.join(FIXTURE_DIR, "fixture.lrb")))
18
+
19
+ assert_fixture_parses(lines)
20
+ end
21
+
22
+ it "loads a literate Ruby file returning annotated lines" do
23
+ lines = LiterateRuby.load(File.join(FIXTURE_DIR, "fixture.lrb"))
24
+
25
+ assert_fixture_parses(lines)
26
+
27
+ assert { FOO == 123 }
28
+ assert { foo() == 2 }
29
+ assert { BAR == 456 }
30
+ end
31
+
32
+ # Leaving this out for now. It works, but until I see someone trying to write libs in lrb, it might not be worth it to
33
+ # rewrite Ruby's load path searching, especially since that's changing.
34
+ # it "requires a literate Ruby file" do
35
+ # LiterateRuby.require(File.join(FIXTURE_DIR, "require_fixture"))
36
+ #
37
+ # assert { bar() == 80 }
38
+ # assert { BAZ == 678 }
39
+ # assert { $".grep(/require_fixture.lrb$/) }
40
+ #
41
+ # deny { LiterateRuby.require(File.join(FIXTURE_DIR, "require_fixture")) }
42
+ # end
43
+
44
+ def assert_fixture_parses(lines)
45
+ expected = [
46
+ [:data,
47
+ [
48
+ [1, "FOO is declared to be 123\n"],
49
+ [2, "Let's test multines\n"],
50
+ [3, "\n"],
51
+ [4, "And paragraph breaks\n"]
52
+ ]
53
+ ],
54
+ [:code,
55
+ [
56
+ [5, " FOO = 123\n"],
57
+ [6, " def foo\n"],
58
+ [7, " 1 + 1\n"],
59
+ [8, " end\n"]
60
+ ]
61
+ ],
62
+ [:data,
63
+ [
64
+ [9, "\n"],
65
+ [10, "BAR is 456\n"],
66
+ [11, "\n"]
67
+ ]
68
+ ],
69
+ [:code,
70
+ [
71
+ [13, "BAR = \n"],
72
+ [14, " 456\n"]
73
+ ]
74
+ ]
75
+ ]
76
+
77
+ assert { lines == expected}
78
+ end
79
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: literate_ruby
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Andrew O'Brien
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-24 00:00:00 -04:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: Literate Ruby is a small preprocessor that allows embedding code within text files and then loading them as programs.
18
+ email:
19
+ - obrien.andrew@gmail.com
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files: []
25
+
26
+ files:
27
+ - .gitignore
28
+ - .infinity_test
29
+ - Gemfile
30
+ - LICENSE
31
+ - README.textile
32
+ - Rakefile
33
+ - lib/literate_ruby.rb
34
+ - lib/literate_ruby/version.rb
35
+ - literate_ruby.gemspec
36
+ - test/fixtures/fixture.lrb
37
+ - test/fixtures/require_fixture.lrb
38
+ - test/literate_ruby_test.rb
39
+ has_rdoc: true
40
+ homepage: http://github.com/AndrewO/literate_ruby
41
+ licenses: []
42
+
43
+ post_install_message:
44
+ rdoc_options: []
45
+
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ requirements: []
61
+
62
+ rubyforge_project: literate_ruby
63
+ rubygems_version: 1.5.0
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Don't comment your code. Code your comments.
67
+ test_files:
68
+ - test/fixtures/fixture.lrb
69
+ - test/fixtures/require_fixture.lrb
70
+ - test/literate_ruby_test.rb