md_inc 0.2.9 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +21 -1
- data/lib/md_inc/md_inc_commands.rb +57 -5
- data/lib/md_inc/version.rb +1 -1
- data/lib/md_inc.rb +15 -5
- data/spec/md_inc_spec.rb +57 -10
- data/spec/new_commands.rb +5 -1
- metadata +2 -2
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -16,6 +16,11 @@ Or install it yourself as:
|
|
16
16
|
|
17
17
|
$ gem install md_inc
|
18
18
|
|
19
|
+
**Note that with version 0.3.0 the API for adding
|
20
|
+
new commands has changed. You command methodss
|
21
|
+
should be ordinary methods, not module methods
|
22
|
+
as before.**
|
23
|
+
|
19
24
|
## Usage
|
20
25
|
|
21
26
|
MdInc is a simple text inclusion filter intended for use
|
@@ -61,7 +66,22 @@ And you can exclude lines based on a regular expression:
|
|
61
66
|
lines that contain DONTWANT
|
62
67
|
.skip(/DONTWANT/, inc('file1'))
|
63
68
|
|
64
|
-
|
69
|
+
Along with .commands there are also ..commands. The
|
70
|
+
difference is that ..command can handle inline text.
|
71
|
+
Here's an example that makes all the lines uppercase:
|
72
|
+
|
73
|
+
..upcase_content
|
74
|
+
some text
|
75
|
+
that will
|
76
|
+
become uppercase
|
77
|
+
..end
|
78
|
+
|
79
|
+
If your command starts with an .., md\_inc will gather up
|
80
|
+
all of the following lines until it hits a ..end and
|
81
|
+
makes those lines available to the command via the
|
82
|
+
`content` method.
|
83
|
+
|
84
|
+
As you can probably guess from the examples,
|
65
85
|
the MdInc dot commands are really just inline Ruby
|
66
86
|
code that gets executed during file processing.
|
67
87
|
Because of this it's easy to extend MdInc with
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module MdInc
|
2
2
|
module Commands
|
3
|
-
class << self
|
4
3
|
def root(path)
|
5
4
|
@root = path
|
6
5
|
end
|
@@ -9,15 +8,64 @@ module MdInc
|
|
9
8
|
@root ? File.join(@root, path) : path
|
10
9
|
end
|
11
10
|
|
11
|
+
def content
|
12
|
+
@content
|
13
|
+
end
|
14
|
+
|
15
|
+
def process_file(file_name)
|
16
|
+
process(File.read(file_name))
|
17
|
+
end
|
18
|
+
|
12
19
|
def process(content)
|
13
20
|
output = process_lines(content.split("\n"))
|
14
21
|
output.flatten.join("\n")
|
15
22
|
end
|
16
23
|
|
17
24
|
def process_lines(lines)
|
18
|
-
|
19
|
-
|
25
|
+
result = []
|
26
|
+
until lines.empty?
|
27
|
+
line = lines.shift
|
28
|
+
ltype = line_type(line)
|
29
|
+
|
30
|
+
if ltype == :multi_line_cmd
|
31
|
+
result +=process_multiline_cmd(line, lines)
|
32
|
+
elsif ltype == :single_line_cmd
|
33
|
+
result << process_single_line_cmd(line)
|
34
|
+
else
|
35
|
+
result << line
|
36
|
+
end
|
20
37
|
end
|
38
|
+
result
|
39
|
+
end
|
40
|
+
|
41
|
+
def line_type(line)
|
42
|
+
if %{. ..}.include?(line)
|
43
|
+
:text
|
44
|
+
elsif line[0,2] == '..'
|
45
|
+
:multi_line_cmd
|
46
|
+
elsif line[0,1] == '.'
|
47
|
+
:single_line_cmd
|
48
|
+
else
|
49
|
+
:text
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def process_single_line_cmd(line)
|
54
|
+
#puts "single line cmd: #{line}"
|
55
|
+
instance_eval(line[1..-1])
|
56
|
+
end
|
57
|
+
|
58
|
+
def process_multiline_cmd(line, lines)
|
59
|
+
content_lines = []
|
60
|
+
until lines.empty? || (lines.first =~ /^..end/)
|
61
|
+
content_lines << lines.shift
|
62
|
+
end
|
63
|
+
lines.shift unless lines.empty?
|
64
|
+
save_content = @content
|
65
|
+
@content = content_lines
|
66
|
+
result = instance_eval(line[2..-1])
|
67
|
+
@content = @save_content
|
68
|
+
result
|
21
69
|
end
|
22
70
|
|
23
71
|
def x(*args)
|
@@ -42,7 +90,7 @@ module MdInc
|
|
42
90
|
if language.nil?
|
43
91
|
lines.map {|l| l.rstrip.prepend(' ')}
|
44
92
|
else
|
45
|
-
["```#{language}"] + lines + ["```"]
|
93
|
+
["```#{language}"] + lines + ["```"]
|
46
94
|
end
|
47
95
|
end
|
48
96
|
|
@@ -75,6 +123,10 @@ module MdInc
|
|
75
123
|
lines.map {|l| l[min_indent..-1]}
|
76
124
|
end
|
77
125
|
|
126
|
+
def upcase_content
|
127
|
+
content.map {|l| l.upcase}
|
128
|
+
end
|
129
|
+
|
78
130
|
private
|
79
131
|
|
80
132
|
def min_indent(lines)
|
@@ -85,6 +137,6 @@ module MdInc
|
|
85
137
|
def indent_depth(s)
|
86
138
|
/^ */.match(s).end(0)
|
87
139
|
end
|
140
|
+
|
88
141
|
end
|
89
|
-
end
|
90
142
|
end
|
data/lib/md_inc/version.rb
CHANGED
data/lib/md_inc.rb
CHANGED
@@ -1,22 +1,32 @@
|
|
1
1
|
require 'md_inc/version'
|
2
2
|
require 'md_inc/md_inc_commands'
|
3
|
+
require 'ostruct'
|
3
4
|
|
4
5
|
module MdInc
|
5
6
|
class TextProcessor
|
6
|
-
|
7
|
-
|
7
|
+
attr_accessor :root
|
8
|
+
|
9
|
+
def initialize(options={})
|
10
|
+
@options = options
|
8
11
|
end
|
9
12
|
|
10
13
|
def process(string)
|
11
|
-
|
14
|
+
context = OpenStruct.new(@options)
|
15
|
+
context.root = root
|
16
|
+
context.options = @options
|
17
|
+
context.extend Commands
|
18
|
+
if @options[:modules]
|
19
|
+
@options[:modules].each {|m| context.extend m}
|
20
|
+
end
|
21
|
+
context.process(string)
|
12
22
|
end
|
13
23
|
|
14
24
|
def process_stream(stream)
|
15
|
-
|
25
|
+
process(stream.read)
|
16
26
|
end
|
17
27
|
|
18
28
|
def process_file(path)
|
19
|
-
|
29
|
+
process(File.read(path))
|
20
30
|
end
|
21
31
|
end
|
22
32
|
end
|
data/spec/md_inc_spec.rb
CHANGED
@@ -2,14 +2,20 @@ require 'md_inc'
|
|
2
2
|
require 'fileutils'
|
3
3
|
|
4
4
|
describe MdInc::Commands do
|
5
|
+
let(:context) do
|
6
|
+
o = Object.new
|
7
|
+
o.extend MdInc::Commands
|
8
|
+
o
|
9
|
+
end
|
10
|
+
|
5
11
|
context '#code' do
|
6
12
|
it 'uses git style tagging if a language is supplied' do
|
7
|
-
output =
|
13
|
+
output = context.code("java", %w{foo})
|
8
14
|
output.should == [ "```java", "foo", "```"]
|
9
15
|
end
|
10
16
|
|
11
17
|
it 'uses traditional code indenting if a language is not supplied' do
|
12
|
-
output =
|
18
|
+
output = context.code(nil, %w{foo})
|
13
19
|
output.should == [ " foo"]
|
14
20
|
end
|
15
21
|
end
|
@@ -18,12 +24,12 @@ describe MdInc::Commands do
|
|
18
24
|
let(:lines) { %w{foo skip1 skip2 bar skip3 baz skip4 skip5} }
|
19
25
|
|
20
26
|
it 'skips the lines that match the regular expression' do
|
21
|
-
output =
|
27
|
+
output = context.skip(/skip/, lines)
|
22
28
|
output.should == %w{foo bar baz}
|
23
29
|
end
|
24
30
|
|
25
31
|
it 'doesnt skip the lines that down match the regular expression' do
|
26
|
-
output =
|
32
|
+
output = context.skip(/no match/, lines)
|
27
33
|
output.should == lines
|
28
34
|
end
|
29
35
|
end
|
@@ -32,12 +38,12 @@ describe MdInc::Commands do
|
|
32
38
|
let(:lines) { %w{aaa bbb ccc ddd eee} }
|
33
39
|
|
34
40
|
it 'returns the lines between the patterns, exclusive' do
|
35
|
-
output =
|
41
|
+
output = context.between(/aaa/, /ddd/, lines)
|
36
42
|
output.should == %w{bbb ccc}
|
37
43
|
end
|
38
44
|
|
39
45
|
it 'will skip the whole output if first re doesnt match' do
|
40
|
-
output =
|
46
|
+
output = context.between(/no match/, /ccc/, lines)
|
41
47
|
output.should == []
|
42
48
|
end
|
43
49
|
end
|
@@ -45,24 +51,33 @@ describe MdInc::Commands do
|
|
45
51
|
context '#normalize_indent' do
|
46
52
|
it 'does nothing to non-indented lines' do
|
47
53
|
lines = %w{aaa, bbb, ccc}
|
48
|
-
output =
|
54
|
+
output = context.normalize_indent(lines)
|
49
55
|
output.should == lines
|
50
56
|
end
|
51
57
|
|
52
58
|
it 'does nothing to lines with at least one non-indented line' do
|
53
59
|
lines = [' aaa', 'bbb', ' ccc']
|
54
|
-
output =
|
60
|
+
output = context.normalize_indent(lines)
|
55
61
|
output.should == lines
|
56
62
|
end
|
57
63
|
|
58
64
|
it 'unindents so that the least indented line has no indent' do
|
59
65
|
lines = [' aaa', ' bbb', ' ccc']
|
60
|
-
output =
|
66
|
+
output = context.normalize_indent(lines)
|
61
67
|
output.should == ['aaa', ' bbb', ' ccc']
|
62
68
|
end
|
63
69
|
|
64
70
|
end
|
71
|
+
end
|
72
|
+
|
73
|
+
module TestModule
|
74
|
+
def test_cmd
|
75
|
+
['line 1 from module', 'line 2 from module']
|
76
|
+
end
|
65
77
|
|
78
|
+
def return_option(name)
|
79
|
+
[options[name]]
|
80
|
+
end
|
66
81
|
end
|
67
82
|
|
68
83
|
describe MdInc::TextProcessor do
|
@@ -141,7 +156,39 @@ describe MdInc::TextProcessor do
|
|
141
156
|
it 'can do recursive inclusion' do
|
142
157
|
text = "first\n.inc 'temp3'\nlast"
|
143
158
|
output = mdi.process(text)
|
144
|
-
output.should == "first\ntemp3 line1\naaa\nbbb\ntemp3 line3\nlast"
|
159
|
+
output.should == "first\ntemp3 line1\naaa\nbbb\ntemp3 line3\nlast"
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'can optionally include other modules for commands' do
|
163
|
+
processor = MdInc::TextProcessor.new :modules => [TestModule]
|
164
|
+
text = "first\n.test_cmd\nlast"
|
165
|
+
output = processor.process(text)
|
166
|
+
output.should == "first\nline 1 from module\nline 2 from module\nlast"
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'can asscess the options hash from inside of a command' do
|
170
|
+
processor = MdInc::TextProcessor.new :modules => [TestModule], :color => "GREEN"
|
171
|
+
text = "first\n.return_option :color\nlast"
|
172
|
+
output = processor.process(text)
|
173
|
+
output.should == "first\nGREEN\nlast"
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'has a working multiline example command in upcase_content' do
|
177
|
+
text = "first\n..upcase_content\naaa\nbbb\nccc\n..end\nlast"
|
178
|
+
output = mdi.process(text)
|
179
|
+
output.should == "first\nAAA\nBBB\nCCC\nlast"
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'handles multiline commands correctly' do
|
183
|
+
text = ".x require 'new_commands'\nfirst\n..multi_up\naaa\nbbb\n..end\nccc"
|
184
|
+
output = mdi.process(text)
|
185
|
+
output.should == "first\nAAA\nBBB\nccc"
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'handles .. as text, not as a multiline command' do
|
189
|
+
text = "\nfirst\n..\nlast"
|
190
|
+
output = mdi.process(text)
|
191
|
+
output.should == text
|
145
192
|
end
|
146
193
|
end
|
147
194
|
end
|
data/spec/new_commands.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: md_inc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-16 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: MdInc is a simple text inclusion utility (it sucks in files) intended
|
15
15
|
for use with markdown and similar utilities.
|