literate-programming 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0579c7998d6a577731d88aaf496b921958e1c6c7
4
+ data.tar.gz: 9e080bfd77245430a9cf245526651510d308c0c9
5
+ SHA512:
6
+ metadata.gz: ef5992afcf34d3bfcf24608850b4d0d5f6cb9eab9989315fb22ebf3c739bbae6ed2f84c0ea8ef60b38f8c87d565b32b62e05743e9ea07f4b198a293991b31d37
7
+ data.tar.gz: a54eb1c3414d1d6a74dffde4897dd9d898a6362d564acfcaecb8224502f2ee7a33f89b6a1090a30a2fa4b12befed28e5aa118a6a48cfd30aaa7873637a06090f
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in literate-programming.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 pixie-grasper
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # Literate Programming for Ruby and Markdown!
2
+
3
+ Let us Literate Programming!
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'literate-programming'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install literate-programming
20
+
21
+ ### Installation from repository
22
+
23
+ You are also able to install this gem from github repository.
24
+ ```bash
25
+ $ git clone https://github.com/pixie-grasper/literate-programming.git
26
+ $ cd literate-programming
27
+ $ rake install
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ - How to Use?
33
+
34
+ ```bash
35
+ $ rtangle example.wrb # to get example.rb
36
+ $ rweave example.wrb # to get example.md
37
+ ```
38
+
39
+ ## Examples
40
+ - Hello, world!
41
+
42
+ First, write hellow.wrb
43
+ ```
44
+ First, define the Hello, world!
45
+ [[hello-world]] =
46
+ "Hello, world!"
47
+
48
+ Next, define Main Program; 'Hello, world!'
49
+ [[*]] =
50
+ def main
51
+ p [[hello-world]]
52
+ end
53
+
54
+ Finaly, call the main.
55
+ [[*]] +=
56
+ main
57
+ ```
58
+
59
+ Second, tangle it!
60
+ ```bash
61
+ $ rtangle hello.wrb
62
+ ```
63
+
64
+ Finally, you will get hello.rb
65
+ ```ruby
66
+ def main
67
+ p "Hello, world!"
68
+ end
69
+
70
+ main
71
+ ```
72
+
73
+ ## License
74
+
75
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
76
+
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new 'spec'
5
+ task :default => :spec
data/bin/rtangle ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'literate/programming'
4
+
5
+ raise if ARGV.length < 1
6
+ ifname = ARGV[0]
7
+ ofname = File.dirname(ifname) + '/' + File.basename(ifname, '.wrb') + '.rb'
8
+ inst = Literate::Programming.new File.open(ifname, 'r').read
9
+ File.open(ofname, 'w').write inst.to_ruby
data/bin/rweave ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'literate/programming'
4
+
5
+ raise if ARGV.length < 1
6
+ ifname = ARGV[0]
7
+ ofname = File.dirname(ifname) + '/' + File.basename(ifname, '.wrb') + '.md'
8
+ inst = Literate::Programming.new File.open(ifname, 'r').read
9
+ File.open(ofname, 'w').write inst.to_md
@@ -0,0 +1,3 @@
1
+ Simple Case 1.
2
+ [[*]] =
3
+ p 'Hello, world!'
@@ -0,0 +1,7 @@
1
+ Simple Case 2.
2
+ [[hello-world]] =
3
+ 'Hello, world!'
4
+
5
+ The main program says hello!
6
+ [[*]] =
7
+ p [[hello-world]]
@@ -0,0 +1,17 @@
1
+ Simple Case 3.
2
+ [[*]] =
3
+ def main
4
+ [[main-body]]
5
+ end
6
+
7
+ The main function says hello-world
8
+ [[main-body]] =
9
+ p [[hello-world]]
10
+
11
+ Definition of the hello-world is a 'Hello, world!'
12
+ [[hello-world]] =
13
+ 'Hello, world!'
14
+
15
+ Finally, call the main function.
16
+ [[*]] +=
17
+ main
@@ -0,0 +1,36 @@
1
+ Template Case 1.
2
+ [[*]] =
3
+ def main
4
+ [[main-body]]
5
+ end
6
+
7
+ Sing a song ''99 bottles of beer''
8
+ [[main-body]] =
9
+ [[bottles:100]]
10
+
11
+ General case, sing below
12
+ [[bottles:@]] =
13
+ puts '@0 bottles of beer on the wall, @0 bottles of beer.'
14
+ puts 'Take one down and pass it around, @@(@0 - 1) bottles of beer on the wall.'
15
+ [[bottles:@@(@0 - 1)]]
16
+
17
+ When number of bottles == 2
18
+ [[bottles:2]] =
19
+ puts '2 bottles of beer on the wall, 2 bottles of beer.'
20
+ puts 'Take one down and pass it around, 1 bottle of beer on the wall.'
21
+ [[bottles:1]]
22
+
23
+ When number of bottles == 1
24
+ [[bottles:1]] =
25
+ puts '1 bottle of beer on the wall, 1 bottle of beer.'
26
+ puts 'Take one down and pass it around, no more bottles of beer on the wall.'
27
+ [[bottles:0]]
28
+
29
+ When no rest bottles...
30
+ [[bottles:0]] =
31
+ puts 'No more bottles of beer on the wall, no more bottles of beer.'
32
+ puts 'Go to the store and buy some more, 99 bottles of beer on the wall.'
33
+
34
+ Finally, call the main function.
35
+ [[*]] +=
36
+ main
@@ -0,0 +1,27 @@
1
+ Template Case 2.
2
+ [[*]] =
3
+ class Main
4
+ [[main-body]]
5
+ end
6
+
7
+ It is free to use @ unless it is followed by a number.
8
+ It is also free to use @@ unless it is followed by left parent.
9
+ [[main-body]] =
10
+ def initialize
11
+ @x = @@default_x
12
+ end
13
+
14
+ If @@ is followed by left parent, it will evaluated by the rtangle.
15
+ For example, an rtangled below one will equals to '@@default_x = 10'
16
+ [[main-body]] +=
17
+ @@default_x = @@(1 + 2 + 3 + 4)
18
+
19
+ How Main.new.run works?
20
+ [[main-body]] +=
21
+ def run
22
+ p 'Hello!'
23
+ end
24
+
25
+ Finally, instanciate Main and run it!
26
+ [[*]] +=
27
+ Main.new.run
@@ -0,0 +1,5 @@
1
+ module Literate
2
+ class Programming
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,188 @@
1
+ require "literate/programming/version"
2
+
3
+ module Literate
4
+ class Programming
5
+ def initialize(src = "", source: nil, tabstop: 2)
6
+ @source = source || src
7
+ @tabstop = tabstop
8
+ end
9
+
10
+ def to_ruby
11
+ convert[:rb]
12
+ end
13
+
14
+ def to_md
15
+ convert[:md]
16
+ end
17
+
18
+ def convert
19
+ current_mode = :text
20
+ md = ""
21
+ table = {}
22
+ current_code = nil
23
+ current_label = nil
24
+ operator = nil
25
+ @source.split($/).each do |line|
26
+ old_mode = current_mode
27
+ case current_mode
28
+ when :text
29
+ if line.match /^[ \t]*\[\[([^\]]+)\]\][ \t]*(\+?=|<<)[ \t]*$/ then
30
+ current_mode = :code
31
+ current_code = ''
32
+ current_label = $1
33
+ case $2
34
+ when '='
35
+ operator = :assign
36
+ when '+=', '<<'
37
+ operator = :append
38
+ end
39
+ end
40
+ when :code
41
+ if line.match /^[ \t]*$/ then
42
+ current_mode = :text
43
+ else
44
+ line = line.match(/^[ \t]*/).post_match
45
+ end
46
+ end
47
+ case current_mode
48
+ when :text
49
+ if old_mode == :code then
50
+ case operator
51
+ when :assign
52
+ raise if table[current_label]
53
+ table[current_label] = current_code
54
+ when :append
55
+ table[current_label] ||= ''
56
+ table[current_label] << $/ << current_code
57
+ end
58
+ md << '```' << $/ << $/
59
+ else
60
+ md << line << $/
61
+ end
62
+ when :code
63
+ if old_mode == :code then
64
+ current_code << line << $/
65
+ md << line << $/
66
+ else
67
+ md << '```ruby:' << current_label
68
+ md << ' append' if operator == :append
69
+ md << $/
70
+ end
71
+ end
72
+ end
73
+ if current_mode == :code then
74
+ case operator
75
+ when :assign
76
+ table[current_label] = current_code
77
+ when :append
78
+ table[current_label] ||= ''
79
+ table[current_label] << $/ << current_code
80
+ end
81
+ md << '```' << $/
82
+ end
83
+ table['*'] ||= ''
84
+ return {rb: indent_code(expand(table)), md: indent_text(md)}
85
+ end
86
+
87
+ def expand(table)
88
+ processed = ''
89
+ processing = '[[*]]'
90
+ while processing.match /^((?:[^\[]|\[[^\[])*)\[\[([^\]]+)\]\]/m
91
+ processed << $1
92
+ expanding = $2
93
+ follow = $~.post_match
94
+ if table.member? expanding then
95
+ processing = expand_template(table[expanding], nil).chomp
96
+ elsif expanding.match /^([^:]+):([^,]+)(,[^,]+)*$/ then
97
+ true_expanding = $1 + ':@'
98
+ args = $~.to_a[2..-2]
99
+ raise 'undefined ' + expanding unless table.member? true_expanding
100
+ processing = expand_template(table[true_expanding], args).chomp
101
+ else
102
+ raise 'undefined ' + expanding
103
+ end
104
+ processing << follow
105
+ end
106
+ return processed << processing
107
+ end
108
+
109
+ def expand_template(string, args)
110
+ processed = ''
111
+ processing = string
112
+ while processing.match /^((?:[^@]|@[^0-9@])*)@/m
113
+ processed << $1
114
+ follow = $~.post_match
115
+ if follow.match /^(0|[1-9][0-9]*)/m then
116
+ # @num -> args[num]
117
+ processed << args[$1.to_i]
118
+ processing = $~.post_match
119
+ elsif follow.match /^@/m then
120
+ follow = $~.post_match
121
+ if follow.match /^(?<paren>\((?:[^()]|\g<paren>)*\))/m then
122
+ # @@(expr) -> eval(expr)
123
+ post_match = $~.post_match
124
+ expanding = eval(expand_template $1, args)
125
+ processed << expanding.to_s
126
+ processing = post_match
127
+ else
128
+ processed << '@@'
129
+ processing = follow
130
+ end
131
+ else
132
+ processed << '@'
133
+ processing = follow
134
+ end
135
+ end
136
+ return processed << processing
137
+ end
138
+
139
+ def indent_code(code)
140
+ indent_level_stack = [-@tabstop]
141
+ ret = ''
142
+ code.split($/).each do |line|
143
+ ret, indent_level_stack = pretty_print_ruby ret, indent_level_stack, line
144
+ end
145
+ return ret
146
+ end
147
+
148
+ def indent_text(text)
149
+ mode = :text
150
+ ret = ''
151
+ indent_level_stack = nil
152
+ text.split($/).each do |line|
153
+ if mode == :text and line.match /^```/ then
154
+ mode = :code
155
+ indent_level_stack = [-@tabstop]
156
+ ret << line << $/
157
+ elsif mode == :text then
158
+ ret << line << $/
159
+ elsif mode == :code and line.match /^```/ then
160
+ mode = :text
161
+ ret << line << $/
162
+ else
163
+ ret, indent_level_stack = pretty_print_ruby ret, indent_level_stack, line
164
+ end
165
+ end
166
+ return ret
167
+ end
168
+
169
+ def pretty_print_ruby(buffer, indent_level_stack, line)
170
+ if line.match /^[ \t]*(else|elsif|ensure|rescue|when)\b/ then
171
+ current_indent_level = indent_level_stack[-1]
172
+ elsif line.match /\b(end)\b/ then
173
+ current_indent_level = indent_level_stack.pop
174
+ else
175
+ current_indent_level = indent_level_stack[-1] + @tabstop
176
+ end
177
+ if line.match /^[ \t]*$/ then
178
+ buffer << $/
179
+ else
180
+ buffer << ' ' * current_indent_level << line << $/
181
+ end
182
+ if line.match /^[ \t]*(begin|class|def|for|while|module)\b/
183
+ indent_level_stack.push current_indent_level
184
+ end
185
+ return buffer, indent_level_stack
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'literate/programming/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'literate-programming'
8
+ spec.version = Literate::Programming::VERSION
9
+ spec.authors = %w!pixie-grasper!
10
+ spec.email = %w!himajinn13sei@gmail.com!
11
+
12
+ spec.summary = %q{Literate Programming for Ruby / Markdown.}
13
+ spec.description = spec.summary
14
+ spec.homepage = 'https://github.com/pixie-grasper/literate-programming'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files`.split($/).find_all do |path|
18
+ not File.basename(path).match %r!^\.!
19
+ end
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.13"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ end
@@ -0,0 +1,498 @@
1
+ require 'spec_helper'
2
+ require 'literate/programming'
3
+
4
+ describe 'literate-programming' do
5
+ it 'empty' do
6
+ inst = Literate::Programming.new
7
+ expect(inst.to_ruby).to eq ""
8
+ expect(inst.to_md).to eq ""
9
+
10
+ inst = Literate::Programming.new ""
11
+ expect(inst.to_ruby).to eq ""
12
+ expect(inst.to_md).to eq ""
13
+
14
+ inst = Literate::Programming.new $/
15
+ expect(inst.to_ruby).to eq ""
16
+ expect(inst.to_md).to eq ""
17
+ end
18
+
19
+ it 'simple case 1' do
20
+ inst = Literate::Programming.new <<-EOW
21
+ Simple Case 1.
22
+ [[*]] =
23
+ p 'Hello, world!'
24
+ EOW
25
+
26
+ expect(inst.to_ruby).to eq <<-EOC
27
+ p 'Hello, world!'
28
+ EOC
29
+
30
+ expect(inst.to_md).to eq <<-EOM
31
+ Simple Case 1.
32
+ ```ruby:*
33
+ p 'Hello, world!'
34
+ ```
35
+ EOM
36
+ end
37
+
38
+ it 'simple case 2' do
39
+ inst = Literate::Programming.new <<-EOM
40
+ Simple Case 2.
41
+ [[hello-world]] =
42
+ 'Hello, world!'
43
+
44
+ The main program says hello!
45
+ [[*]] =
46
+ p [[hello-world]]
47
+ EOM
48
+
49
+ expect(inst.to_ruby).to eq <<-EOC
50
+ p 'Hello, world!'
51
+ EOC
52
+
53
+ expect(inst.to_md).to eq <<-EOM
54
+ Simple Case 2.
55
+ ```ruby:hello-world
56
+ 'Hello, world!'
57
+ ```
58
+
59
+ The main program says hello!
60
+ ```ruby:*
61
+ p [[hello-world]]
62
+ ```
63
+ EOM
64
+ end
65
+
66
+ it 'simple case 3' do
67
+ inst = Literate::Programming.new <<-EOM
68
+ Simple Case 3.
69
+ [[*]] =
70
+ def main
71
+ [[main-body]]
72
+ end
73
+
74
+ The main function says hello-world
75
+ [[main-body]] =
76
+ p [[hello-world]]
77
+
78
+ Definition of the hello-world is a 'Hello, world!'
79
+ [[hello-world]] =
80
+ 'Hello, world!'
81
+
82
+ Finally, call the main function.
83
+ [[*]] +=
84
+ main
85
+ EOM
86
+
87
+ expect(inst.to_ruby).to eq <<-EOC
88
+ def main
89
+ p 'Hello, world!'
90
+ end
91
+
92
+ main
93
+ EOC
94
+
95
+ expect(inst.to_md).to eq <<-EOC
96
+ Simple Case 3.
97
+ ```ruby:*
98
+ def main
99
+ [[main-body]]
100
+ end
101
+ ```
102
+
103
+ The main function says hello-world
104
+ ```ruby:main-body
105
+ p [[hello-world]]
106
+ ```
107
+
108
+ Definition of the hello-world is a 'Hello, world!'
109
+ ```ruby:hello-world
110
+ 'Hello, world!'
111
+ ```
112
+
113
+ Finally, call the main function.
114
+ ```ruby:* append
115
+ main
116
+ ```
117
+ EOC
118
+ end
119
+
120
+ it 'template case 1' do
121
+ inst = Literate::Programming.new <<-EOM
122
+ Template Case 1.
123
+ [[*]] =
124
+ def main
125
+ [[main-body]]
126
+ end
127
+
128
+ Sing a song ''99 bottles of beer''
129
+ [[main-body]] =
130
+ [[bottles:100]]
131
+
132
+ General case, sing below
133
+ [[bottles:@]] =
134
+ puts '@0 bottles of beer on the wall, @0 bottles of beer.'
135
+ puts 'Take one down and pass it around, @@(@0 - 1) bottles of beer on the wall.'
136
+ [[bottles:@@(@0 - 1)]]
137
+
138
+ When number of bottles == 2
139
+ [[bottles:2]] =
140
+ puts '2 bottles of beer on the wall, 2 bottles of beer.'
141
+ puts 'Take one down and pass it around, 1 bottle of beer on the wall.'
142
+ [[bottles:1]]
143
+
144
+ When number of bottles == 1
145
+ [[bottles:1]] =
146
+ puts '1 bottle of beer on the wall, 1 bottle of beer.'
147
+ puts 'Take one down and pass it around, no more bottles of beer on the wall.'
148
+ [[bottles:0]]
149
+
150
+ When no rest bottles...
151
+ [[bottles:0]] =
152
+ puts 'No more bottles of beer on the wall, no more bottles of beer.'
153
+ puts 'Go to the store and buy some more, 99 bottles of beer on the wall.'
154
+
155
+ Finally, call the main function.
156
+ [[*]] +=
157
+ main
158
+ EOM
159
+
160
+ expect(inst.to_ruby).to eq <<-EOC
161
+ def main
162
+ puts '100 bottles of beer on the wall, 100 bottles of beer.'
163
+ puts 'Take one down and pass it around, 99 bottles of beer on the wall.'
164
+ puts '99 bottles of beer on the wall, 99 bottles of beer.'
165
+ puts 'Take one down and pass it around, 98 bottles of beer on the wall.'
166
+ puts '98 bottles of beer on the wall, 98 bottles of beer.'
167
+ puts 'Take one down and pass it around, 97 bottles of beer on the wall.'
168
+ puts '97 bottles of beer on the wall, 97 bottles of beer.'
169
+ puts 'Take one down and pass it around, 96 bottles of beer on the wall.'
170
+ puts '96 bottles of beer on the wall, 96 bottles of beer.'
171
+ puts 'Take one down and pass it around, 95 bottles of beer on the wall.'
172
+ puts '95 bottles of beer on the wall, 95 bottles of beer.'
173
+ puts 'Take one down and pass it around, 94 bottles of beer on the wall.'
174
+ puts '94 bottles of beer on the wall, 94 bottles of beer.'
175
+ puts 'Take one down and pass it around, 93 bottles of beer on the wall.'
176
+ puts '93 bottles of beer on the wall, 93 bottles of beer.'
177
+ puts 'Take one down and pass it around, 92 bottles of beer on the wall.'
178
+ puts '92 bottles of beer on the wall, 92 bottles of beer.'
179
+ puts 'Take one down and pass it around, 91 bottles of beer on the wall.'
180
+ puts '91 bottles of beer on the wall, 91 bottles of beer.'
181
+ puts 'Take one down and pass it around, 90 bottles of beer on the wall.'
182
+ puts '90 bottles of beer on the wall, 90 bottles of beer.'
183
+ puts 'Take one down and pass it around, 89 bottles of beer on the wall.'
184
+ puts '89 bottles of beer on the wall, 89 bottles of beer.'
185
+ puts 'Take one down and pass it around, 88 bottles of beer on the wall.'
186
+ puts '88 bottles of beer on the wall, 88 bottles of beer.'
187
+ puts 'Take one down and pass it around, 87 bottles of beer on the wall.'
188
+ puts '87 bottles of beer on the wall, 87 bottles of beer.'
189
+ puts 'Take one down and pass it around, 86 bottles of beer on the wall.'
190
+ puts '86 bottles of beer on the wall, 86 bottles of beer.'
191
+ puts 'Take one down and pass it around, 85 bottles of beer on the wall.'
192
+ puts '85 bottles of beer on the wall, 85 bottles of beer.'
193
+ puts 'Take one down and pass it around, 84 bottles of beer on the wall.'
194
+ puts '84 bottles of beer on the wall, 84 bottles of beer.'
195
+ puts 'Take one down and pass it around, 83 bottles of beer on the wall.'
196
+ puts '83 bottles of beer on the wall, 83 bottles of beer.'
197
+ puts 'Take one down and pass it around, 82 bottles of beer on the wall.'
198
+ puts '82 bottles of beer on the wall, 82 bottles of beer.'
199
+ puts 'Take one down and pass it around, 81 bottles of beer on the wall.'
200
+ puts '81 bottles of beer on the wall, 81 bottles of beer.'
201
+ puts 'Take one down and pass it around, 80 bottles of beer on the wall.'
202
+ puts '80 bottles of beer on the wall, 80 bottles of beer.'
203
+ puts 'Take one down and pass it around, 79 bottles of beer on the wall.'
204
+ puts '79 bottles of beer on the wall, 79 bottles of beer.'
205
+ puts 'Take one down and pass it around, 78 bottles of beer on the wall.'
206
+ puts '78 bottles of beer on the wall, 78 bottles of beer.'
207
+ puts 'Take one down and pass it around, 77 bottles of beer on the wall.'
208
+ puts '77 bottles of beer on the wall, 77 bottles of beer.'
209
+ puts 'Take one down and pass it around, 76 bottles of beer on the wall.'
210
+ puts '76 bottles of beer on the wall, 76 bottles of beer.'
211
+ puts 'Take one down and pass it around, 75 bottles of beer on the wall.'
212
+ puts '75 bottles of beer on the wall, 75 bottles of beer.'
213
+ puts 'Take one down and pass it around, 74 bottles of beer on the wall.'
214
+ puts '74 bottles of beer on the wall, 74 bottles of beer.'
215
+ puts 'Take one down and pass it around, 73 bottles of beer on the wall.'
216
+ puts '73 bottles of beer on the wall, 73 bottles of beer.'
217
+ puts 'Take one down and pass it around, 72 bottles of beer on the wall.'
218
+ puts '72 bottles of beer on the wall, 72 bottles of beer.'
219
+ puts 'Take one down and pass it around, 71 bottles of beer on the wall.'
220
+ puts '71 bottles of beer on the wall, 71 bottles of beer.'
221
+ puts 'Take one down and pass it around, 70 bottles of beer on the wall.'
222
+ puts '70 bottles of beer on the wall, 70 bottles of beer.'
223
+ puts 'Take one down and pass it around, 69 bottles of beer on the wall.'
224
+ puts '69 bottles of beer on the wall, 69 bottles of beer.'
225
+ puts 'Take one down and pass it around, 68 bottles of beer on the wall.'
226
+ puts '68 bottles of beer on the wall, 68 bottles of beer.'
227
+ puts 'Take one down and pass it around, 67 bottles of beer on the wall.'
228
+ puts '67 bottles of beer on the wall, 67 bottles of beer.'
229
+ puts 'Take one down and pass it around, 66 bottles of beer on the wall.'
230
+ puts '66 bottles of beer on the wall, 66 bottles of beer.'
231
+ puts 'Take one down and pass it around, 65 bottles of beer on the wall.'
232
+ puts '65 bottles of beer on the wall, 65 bottles of beer.'
233
+ puts 'Take one down and pass it around, 64 bottles of beer on the wall.'
234
+ puts '64 bottles of beer on the wall, 64 bottles of beer.'
235
+ puts 'Take one down and pass it around, 63 bottles of beer on the wall.'
236
+ puts '63 bottles of beer on the wall, 63 bottles of beer.'
237
+ puts 'Take one down and pass it around, 62 bottles of beer on the wall.'
238
+ puts '62 bottles of beer on the wall, 62 bottles of beer.'
239
+ puts 'Take one down and pass it around, 61 bottles of beer on the wall.'
240
+ puts '61 bottles of beer on the wall, 61 bottles of beer.'
241
+ puts 'Take one down and pass it around, 60 bottles of beer on the wall.'
242
+ puts '60 bottles of beer on the wall, 60 bottles of beer.'
243
+ puts 'Take one down and pass it around, 59 bottles of beer on the wall.'
244
+ puts '59 bottles of beer on the wall, 59 bottles of beer.'
245
+ puts 'Take one down and pass it around, 58 bottles of beer on the wall.'
246
+ puts '58 bottles of beer on the wall, 58 bottles of beer.'
247
+ puts 'Take one down and pass it around, 57 bottles of beer on the wall.'
248
+ puts '57 bottles of beer on the wall, 57 bottles of beer.'
249
+ puts 'Take one down and pass it around, 56 bottles of beer on the wall.'
250
+ puts '56 bottles of beer on the wall, 56 bottles of beer.'
251
+ puts 'Take one down and pass it around, 55 bottles of beer on the wall.'
252
+ puts '55 bottles of beer on the wall, 55 bottles of beer.'
253
+ puts 'Take one down and pass it around, 54 bottles of beer on the wall.'
254
+ puts '54 bottles of beer on the wall, 54 bottles of beer.'
255
+ puts 'Take one down and pass it around, 53 bottles of beer on the wall.'
256
+ puts '53 bottles of beer on the wall, 53 bottles of beer.'
257
+ puts 'Take one down and pass it around, 52 bottles of beer on the wall.'
258
+ puts '52 bottles of beer on the wall, 52 bottles of beer.'
259
+ puts 'Take one down and pass it around, 51 bottles of beer on the wall.'
260
+ puts '51 bottles of beer on the wall, 51 bottles of beer.'
261
+ puts 'Take one down and pass it around, 50 bottles of beer on the wall.'
262
+ puts '50 bottles of beer on the wall, 50 bottles of beer.'
263
+ puts 'Take one down and pass it around, 49 bottles of beer on the wall.'
264
+ puts '49 bottles of beer on the wall, 49 bottles of beer.'
265
+ puts 'Take one down and pass it around, 48 bottles of beer on the wall.'
266
+ puts '48 bottles of beer on the wall, 48 bottles of beer.'
267
+ puts 'Take one down and pass it around, 47 bottles of beer on the wall.'
268
+ puts '47 bottles of beer on the wall, 47 bottles of beer.'
269
+ puts 'Take one down and pass it around, 46 bottles of beer on the wall.'
270
+ puts '46 bottles of beer on the wall, 46 bottles of beer.'
271
+ puts 'Take one down and pass it around, 45 bottles of beer on the wall.'
272
+ puts '45 bottles of beer on the wall, 45 bottles of beer.'
273
+ puts 'Take one down and pass it around, 44 bottles of beer on the wall.'
274
+ puts '44 bottles of beer on the wall, 44 bottles of beer.'
275
+ puts 'Take one down and pass it around, 43 bottles of beer on the wall.'
276
+ puts '43 bottles of beer on the wall, 43 bottles of beer.'
277
+ puts 'Take one down and pass it around, 42 bottles of beer on the wall.'
278
+ puts '42 bottles of beer on the wall, 42 bottles of beer.'
279
+ puts 'Take one down and pass it around, 41 bottles of beer on the wall.'
280
+ puts '41 bottles of beer on the wall, 41 bottles of beer.'
281
+ puts 'Take one down and pass it around, 40 bottles of beer on the wall.'
282
+ puts '40 bottles of beer on the wall, 40 bottles of beer.'
283
+ puts 'Take one down and pass it around, 39 bottles of beer on the wall.'
284
+ puts '39 bottles of beer on the wall, 39 bottles of beer.'
285
+ puts 'Take one down and pass it around, 38 bottles of beer on the wall.'
286
+ puts '38 bottles of beer on the wall, 38 bottles of beer.'
287
+ puts 'Take one down and pass it around, 37 bottles of beer on the wall.'
288
+ puts '37 bottles of beer on the wall, 37 bottles of beer.'
289
+ puts 'Take one down and pass it around, 36 bottles of beer on the wall.'
290
+ puts '36 bottles of beer on the wall, 36 bottles of beer.'
291
+ puts 'Take one down and pass it around, 35 bottles of beer on the wall.'
292
+ puts '35 bottles of beer on the wall, 35 bottles of beer.'
293
+ puts 'Take one down and pass it around, 34 bottles of beer on the wall.'
294
+ puts '34 bottles of beer on the wall, 34 bottles of beer.'
295
+ puts 'Take one down and pass it around, 33 bottles of beer on the wall.'
296
+ puts '33 bottles of beer on the wall, 33 bottles of beer.'
297
+ puts 'Take one down and pass it around, 32 bottles of beer on the wall.'
298
+ puts '32 bottles of beer on the wall, 32 bottles of beer.'
299
+ puts 'Take one down and pass it around, 31 bottles of beer on the wall.'
300
+ puts '31 bottles of beer on the wall, 31 bottles of beer.'
301
+ puts 'Take one down and pass it around, 30 bottles of beer on the wall.'
302
+ puts '30 bottles of beer on the wall, 30 bottles of beer.'
303
+ puts 'Take one down and pass it around, 29 bottles of beer on the wall.'
304
+ puts '29 bottles of beer on the wall, 29 bottles of beer.'
305
+ puts 'Take one down and pass it around, 28 bottles of beer on the wall.'
306
+ puts '28 bottles of beer on the wall, 28 bottles of beer.'
307
+ puts 'Take one down and pass it around, 27 bottles of beer on the wall.'
308
+ puts '27 bottles of beer on the wall, 27 bottles of beer.'
309
+ puts 'Take one down and pass it around, 26 bottles of beer on the wall.'
310
+ puts '26 bottles of beer on the wall, 26 bottles of beer.'
311
+ puts 'Take one down and pass it around, 25 bottles of beer on the wall.'
312
+ puts '25 bottles of beer on the wall, 25 bottles of beer.'
313
+ puts 'Take one down and pass it around, 24 bottles of beer on the wall.'
314
+ puts '24 bottles of beer on the wall, 24 bottles of beer.'
315
+ puts 'Take one down and pass it around, 23 bottles of beer on the wall.'
316
+ puts '23 bottles of beer on the wall, 23 bottles of beer.'
317
+ puts 'Take one down and pass it around, 22 bottles of beer on the wall.'
318
+ puts '22 bottles of beer on the wall, 22 bottles of beer.'
319
+ puts 'Take one down and pass it around, 21 bottles of beer on the wall.'
320
+ puts '21 bottles of beer on the wall, 21 bottles of beer.'
321
+ puts 'Take one down and pass it around, 20 bottles of beer on the wall.'
322
+ puts '20 bottles of beer on the wall, 20 bottles of beer.'
323
+ puts 'Take one down and pass it around, 19 bottles of beer on the wall.'
324
+ puts '19 bottles of beer on the wall, 19 bottles of beer.'
325
+ puts 'Take one down and pass it around, 18 bottles of beer on the wall.'
326
+ puts '18 bottles of beer on the wall, 18 bottles of beer.'
327
+ puts 'Take one down and pass it around, 17 bottles of beer on the wall.'
328
+ puts '17 bottles of beer on the wall, 17 bottles of beer.'
329
+ puts 'Take one down and pass it around, 16 bottles of beer on the wall.'
330
+ puts '16 bottles of beer on the wall, 16 bottles of beer.'
331
+ puts 'Take one down and pass it around, 15 bottles of beer on the wall.'
332
+ puts '15 bottles of beer on the wall, 15 bottles of beer.'
333
+ puts 'Take one down and pass it around, 14 bottles of beer on the wall.'
334
+ puts '14 bottles of beer on the wall, 14 bottles of beer.'
335
+ puts 'Take one down and pass it around, 13 bottles of beer on the wall.'
336
+ puts '13 bottles of beer on the wall, 13 bottles of beer.'
337
+ puts 'Take one down and pass it around, 12 bottles of beer on the wall.'
338
+ puts '12 bottles of beer on the wall, 12 bottles of beer.'
339
+ puts 'Take one down and pass it around, 11 bottles of beer on the wall.'
340
+ puts '11 bottles of beer on the wall, 11 bottles of beer.'
341
+ puts 'Take one down and pass it around, 10 bottles of beer on the wall.'
342
+ puts '10 bottles of beer on the wall, 10 bottles of beer.'
343
+ puts 'Take one down and pass it around, 9 bottles of beer on the wall.'
344
+ puts '9 bottles of beer on the wall, 9 bottles of beer.'
345
+ puts 'Take one down and pass it around, 8 bottles of beer on the wall.'
346
+ puts '8 bottles of beer on the wall, 8 bottles of beer.'
347
+ puts 'Take one down and pass it around, 7 bottles of beer on the wall.'
348
+ puts '7 bottles of beer on the wall, 7 bottles of beer.'
349
+ puts 'Take one down and pass it around, 6 bottles of beer on the wall.'
350
+ puts '6 bottles of beer on the wall, 6 bottles of beer.'
351
+ puts 'Take one down and pass it around, 5 bottles of beer on the wall.'
352
+ puts '5 bottles of beer on the wall, 5 bottles of beer.'
353
+ puts 'Take one down and pass it around, 4 bottles of beer on the wall.'
354
+ puts '4 bottles of beer on the wall, 4 bottles of beer.'
355
+ puts 'Take one down and pass it around, 3 bottles of beer on the wall.'
356
+ puts '3 bottles of beer on the wall, 3 bottles of beer.'
357
+ puts 'Take one down and pass it around, 2 bottles of beer on the wall.'
358
+ puts '2 bottles of beer on the wall, 2 bottles of beer.'
359
+ puts 'Take one down and pass it around, 1 bottle of beer on the wall.'
360
+ puts '1 bottle of beer on the wall, 1 bottle of beer.'
361
+ puts 'Take one down and pass it around, no more bottles of beer on the wall.'
362
+ puts 'No more bottles of beer on the wall, no more bottles of beer.'
363
+ puts 'Go to the store and buy some more, 99 bottles of beer on the wall.'
364
+ end
365
+
366
+ main
367
+ EOC
368
+
369
+ expect(inst.to_md).to eq <<-EOC
370
+ Template Case 1.
371
+ ```ruby:*
372
+ def main
373
+ [[main-body]]
374
+ end
375
+ ```
376
+
377
+ Sing a song ''99 bottles of beer''
378
+ ```ruby:main-body
379
+ [[bottles:100]]
380
+ ```
381
+
382
+ General case, sing below
383
+ ```ruby:bottles:@
384
+ puts '@0 bottles of beer on the wall, @0 bottles of beer.'
385
+ puts 'Take one down and pass it around, @@(@0 - 1) bottles of beer on the wall.'
386
+ [[bottles:@@(@0 - 1)]]
387
+ ```
388
+
389
+ When number of bottles == 2
390
+ ```ruby:bottles:2
391
+ puts '2 bottles of beer on the wall, 2 bottles of beer.'
392
+ puts 'Take one down and pass it around, 1 bottle of beer on the wall.'
393
+ [[bottles:1]]
394
+ ```
395
+
396
+ When number of bottles == 1
397
+ ```ruby:bottles:1
398
+ puts '1 bottle of beer on the wall, 1 bottle of beer.'
399
+ puts 'Take one down and pass it around, no more bottles of beer on the wall.'
400
+ [[bottles:0]]
401
+ ```
402
+
403
+ When no rest bottles...
404
+ ```ruby:bottles:0
405
+ puts 'No more bottles of beer on the wall, no more bottles of beer.'
406
+ puts 'Go to the store and buy some more, 99 bottles of beer on the wall.'
407
+ ```
408
+
409
+ Finally, call the main function.
410
+ ```ruby:* append
411
+ main
412
+ ```
413
+ EOC
414
+ end
415
+
416
+ it 'template case 2' do
417
+ inst = Literate::Programming.new <<-EOM
418
+ Template Case 2.
419
+ [[*]] =
420
+ class Main
421
+ [[main-body]]
422
+ end
423
+
424
+ It is free to use @ unless it is followed by a number.
425
+ It is also free to use @@ unless it is followed by left parent.
426
+ [[main-body]] =
427
+ def initialize
428
+ @x = @@default_x
429
+ end
430
+
431
+ If @@ is followed by left parent, it will evaluated by the rtangle.
432
+ For example, an rtangled below one will equals to '@@default_x = 10'
433
+ [[main-body]] +=
434
+ @@default_x = @@(1 + 2 + 3 + 4)
435
+
436
+ How Main.new.run works?
437
+ [[main-body]] +=
438
+ def run
439
+ p 'Hello!'
440
+ end
441
+
442
+ Finally, instanciate Main and run it!
443
+ [[*]] +=
444
+ Main.new.run
445
+ EOM
446
+
447
+ expect(inst.to_ruby).to eq <<-EOC
448
+ class Main
449
+ def initialize
450
+ @x = @@default_x
451
+ end
452
+
453
+ @@default_x = 10
454
+
455
+ def run
456
+ p 'Hello!'
457
+ end
458
+ end
459
+
460
+ Main.new.run
461
+ EOC
462
+
463
+ expect(inst.to_md).to eq <<-EOC
464
+ Template Case 2.
465
+ ```ruby:*
466
+ class Main
467
+ [[main-body]]
468
+ end
469
+ ```
470
+
471
+ It is free to use @ unless it is followed by a number.
472
+ It is also free to use @@ unless it is followed by left parent.
473
+ ```ruby:main-body
474
+ def initialize
475
+ @x = @@default_x
476
+ end
477
+ ```
478
+
479
+ If @@ is followed by left parent, it will evaluated by the rtangle.
480
+ For example, an rtangled below one will equals to '@@default_x = 10'
481
+ ```ruby:main-body append
482
+ @@default_x = @@(1 + 2 + 3 + 4)
483
+ ```
484
+
485
+ How Main.new.run works?
486
+ ```ruby:main-body append
487
+ def run
488
+ p 'Hello!'
489
+ end
490
+ ```
491
+
492
+ Finally, instanciate Main and run it!
493
+ ```ruby:* append
494
+ Main.new.run
495
+ ```
496
+ EOC
497
+ end
498
+ end
@@ -0,0 +1,4 @@
1
+ require 'rspec'
2
+
3
+ RSpec.configure do |config|
4
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: literate-programming
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - pixie-grasper
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: Literate Programming for Ruby / Markdown.
56
+ email:
57
+ - himajinn13sei@gmail.com
58
+ executables:
59
+ - rtangle
60
+ - rweave
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - bin/rtangle
69
+ - bin/rweave
70
+ - example/simple-1.wrb
71
+ - example/simple-2.wrb
72
+ - example/simple-3.wrb
73
+ - example/template-1.wrb
74
+ - example/template-2.wrb
75
+ - lib/literate/programming.rb
76
+ - lib/literate/programming/version.rb
77
+ - literate-programming.gemspec
78
+ - spec/lib/literate/programming_spec.rb
79
+ - spec/spec_helper.rb
80
+ homepage: https://github.com/pixie-grasper/literate-programming
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.5.1
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Literate Programming for Ruby / Markdown.
104
+ test_files:
105
+ - spec/lib/literate/programming_spec.rb
106
+ - spec/spec_helper.rb