md_inc 0.2.9 → 0.3.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/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.
|