markdownplus 0.1.0 → 0.2.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 +4 -4
- data/README.md +137 -3
- data/lib/markdownplus.rb +5 -0
- data/lib/markdownplus/directive_parser.rb +17 -0
- data/lib/markdownplus/directives.treetop +33 -0
- data/lib/markdownplus/github_renderer.rb +19 -0
- data/lib/markdownplus/handler.rb +120 -0
- data/lib/markdownplus/handler_registry.rb +17 -0
- data/lib/markdownplus/literals.rb +101 -0
- data/lib/markdownplus/parser.rb +75 -125
- data/lib/markdownplus/version.rb +1 -1
- data/markdownplus.gemspec +1 -0
- data/spec/directive_parser_spec.rb +275 -0
- data/spec/fixtures/bad_json.json +1 -0
- data/spec/fixtures/directives.html +110 -0
- data/spec/fixtures/directives.mdp +28 -0
- data/spec/fixtures/fake.csv +21 -0
- data/spec/fixtures/fake.json +1 -0
- data/spec/fixtures/simple.mdp +2 -6
- data/spec/fixtures/variables.html +29 -0
- data/spec/fixtures/variables.mdp +14 -0
- data/spec/parser_spec.rb +124 -47
- metadata +38 -4
- data/spec/fixtures/include.mdp +0 -33
data/lib/markdownplus/parser.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
require 'csv'
|
2
2
|
require 'json'
|
3
3
|
require 'open-uri'
|
4
|
-
require 'pygments'
|
5
|
-
require 'redcarpet'
|
6
4
|
|
7
5
|
module Markdownplus
|
8
6
|
class Parser
|
9
|
-
attr_reader :
|
7
|
+
attr_reader :input
|
10
8
|
attr_accessor :current_block
|
11
9
|
|
12
10
|
def self.parse(value)
|
@@ -16,7 +14,7 @@ module Markdownplus
|
|
16
14
|
end
|
17
15
|
|
18
16
|
def initialize(value=nil)
|
19
|
-
@
|
17
|
+
@input = value
|
20
18
|
end
|
21
19
|
|
22
20
|
def blocks
|
@@ -30,38 +28,42 @@ module Markdownplus
|
|
30
28
|
blocks.select { |b| b.class == CodeBlock }
|
31
29
|
end
|
32
30
|
|
33
|
-
def includable_blocks
|
34
|
-
code_blocks.select(&:includable?)
|
35
|
-
end
|
36
|
-
|
37
31
|
def executable_blocks
|
38
32
|
code_blocks.select(&:executable?)
|
39
33
|
end
|
40
34
|
|
41
|
-
def
|
42
|
-
blocks.collect { |b| b.
|
35
|
+
def input_markdown
|
36
|
+
blocks.collect { |b| b.input_markdown }.join
|
37
|
+
end
|
38
|
+
|
39
|
+
def output_markdown
|
40
|
+
blocks.collect { |b| b.output_markdown }.join
|
43
41
|
end
|
44
42
|
|
45
43
|
def html
|
46
|
-
markdown_renderer.render(
|
44
|
+
markdown_renderer.render(output_markdown)
|
47
45
|
end
|
48
46
|
|
49
47
|
def markdown_renderer
|
50
|
-
Redcarpet::Markdown.new(
|
48
|
+
Redcarpet::Markdown.new(GithubRenderer, fenced_code_blocks: true)
|
51
49
|
end
|
52
50
|
|
53
51
|
def lines
|
54
|
-
@lines ||=
|
52
|
+
@lines ||= input.split("\n")
|
55
53
|
end
|
56
54
|
|
57
|
-
def
|
58
|
-
|
55
|
+
def variables
|
56
|
+
@variables ||= {}
|
59
57
|
end
|
60
58
|
|
61
59
|
def warnings
|
62
60
|
blocks.collect { |b| b.warnings }.flatten
|
63
61
|
end
|
64
62
|
|
63
|
+
def errors
|
64
|
+
blocks.collect { |b| b.errors }.flatten
|
65
|
+
end
|
66
|
+
|
65
67
|
def each_line(&block)
|
66
68
|
if block_given?
|
67
69
|
lines.each do |line|
|
@@ -71,45 +73,52 @@ module Markdownplus
|
|
71
73
|
end
|
72
74
|
|
73
75
|
def parse
|
76
|
+
block_number = 0
|
74
77
|
each_line do |line|
|
75
78
|
matcher = line.match(/\s*`{3,}\s*(\S*)\s*/)
|
76
79
|
if matcher
|
77
|
-
if self.current_block && self.current_block.
|
80
|
+
if self.current_block && self.current_block.is_a?(CodeBlock)
|
78
81
|
self.blocks << self.current_block
|
79
82
|
self.current_block = nil
|
83
|
+
block_number += 1
|
80
84
|
else
|
81
85
|
self.blocks << self.current_block if self.current_block
|
82
|
-
self.current_block = CodeBlock.new(matcher[1])
|
86
|
+
self.current_block = CodeBlock.new(block_number, matcher[1])
|
83
87
|
end
|
84
88
|
else
|
85
|
-
self.current_block ||= TextBlock.new
|
89
|
+
self.current_block ||= TextBlock.new(block_number)
|
86
90
|
self.current_block.append line
|
87
91
|
end
|
88
92
|
end
|
89
93
|
self.blocks << self.current_block if self.current_block
|
90
94
|
end
|
91
95
|
|
92
|
-
def
|
93
|
-
|
94
|
-
block.
|
96
|
+
def execute
|
97
|
+
self.executable_blocks.each do |block|
|
98
|
+
block.execute(self.variables)
|
95
99
|
end
|
96
100
|
end
|
97
101
|
end
|
98
102
|
|
99
103
|
class Block
|
100
|
-
|
101
|
-
|
104
|
+
attr_reader :block_number
|
105
|
+
def initialize(block_number)
|
106
|
+
@block_number = block_number
|
102
107
|
end
|
103
|
-
|
104
|
-
|
108
|
+
|
109
|
+
def input
|
110
|
+
@input ||= ""
|
111
|
+
end
|
112
|
+
def input=(value)
|
113
|
+
@input = value
|
105
114
|
end
|
106
115
|
|
107
116
|
def lines
|
108
|
-
self.
|
117
|
+
self.input.split("\n")
|
109
118
|
end
|
110
119
|
|
111
120
|
def append(line)
|
112
|
-
self.
|
121
|
+
self.input += "#{line}\n"
|
113
122
|
end
|
114
123
|
|
115
124
|
def errors
|
@@ -122,125 +131,66 @@ module Markdownplus
|
|
122
131
|
end
|
123
132
|
|
124
133
|
class TextBlock < Block
|
125
|
-
|
126
|
-
|
134
|
+
|
135
|
+
def input_markdown
|
136
|
+
self.input
|
137
|
+
end
|
138
|
+
|
139
|
+
def output_markdown
|
140
|
+
self.input
|
127
141
|
end
|
128
142
|
end
|
129
143
|
|
130
144
|
class CodeBlock < Block
|
131
|
-
attr_reader :
|
145
|
+
attr_reader :directive, :program
|
146
|
+
attr_accessor :output
|
132
147
|
|
133
|
-
def initialize(value=nil)
|
134
|
-
@
|
135
|
-
|
148
|
+
def initialize(block_number, value=nil)
|
149
|
+
@block_number = block_number
|
150
|
+
@directive = value
|
136
151
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
152
|
+
if @directive.match(/\(/)
|
153
|
+
begin
|
154
|
+
@program ||= Markdownplus::DirectiveParser.parse(@directive)
|
155
|
+
rescue => e
|
156
|
+
errors << e.message
|
157
|
+
end
|
143
158
|
end
|
144
159
|
end
|
145
160
|
|
146
|
-
def
|
147
|
-
|
161
|
+
def functions
|
162
|
+
program.functions if program!=nil
|
148
163
|
end
|
149
164
|
|
150
165
|
def executable?
|
151
|
-
|
166
|
+
(functions!=nil && functions.size>0)
|
152
167
|
end
|
153
168
|
|
154
|
-
def
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
self.warnings << "More than one line given" if lines.count > 1
|
160
|
-
begin
|
161
|
-
self.source = open(lines.first).read
|
162
|
-
rescue => e
|
163
|
-
self.errors << "Error opening [#{lines.first}] [#{e.message}]"
|
164
|
-
end
|
169
|
+
def execute(variables)
|
170
|
+
self.output = self.input
|
171
|
+
if functions
|
172
|
+
self.functions.each do |function|
|
173
|
+
self.output = function.execute(self.output, variables, self.warnings, self.errors)
|
165
174
|
end
|
166
|
-
directives.shift
|
167
175
|
end
|
176
|
+
self.output
|
168
177
|
end
|
169
178
|
|
170
|
-
def
|
171
|
-
|
179
|
+
def input_markdown
|
180
|
+
s = input
|
181
|
+
if s.end_with?("\n")
|
182
|
+
result = "```#{directive}\n#{input}```\n"
|
183
|
+
else
|
184
|
+
result = "```#{directive}\n#{input}\n```\n"
|
185
|
+
end
|
172
186
|
end
|
173
187
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
# method = matcher[1].strip
|
178
|
-
# params = matcher[2].split(",").collect { |p| p.strip }
|
179
|
-
# end
|
180
|
-
# end
|
181
|
-
end
|
188
|
+
def output_markdown
|
189
|
+
self.output
|
190
|
+
end
|
182
191
|
|
183
|
-
|
184
|
-
|
185
|
-
# items = string.split(",").collect do |item|
|
186
|
-
# matcher = item.match(/(.*?)\((.*)\)/)
|
187
|
-
# if matcher
|
188
|
-
# name = matcher[1].strip
|
189
|
-
# params = parse(matcher[2])
|
190
|
-
# Method.new(name: name, params: params)
|
191
|
-
# else
|
192
|
-
# Param.new(item.strip)
|
193
|
-
# end
|
194
|
-
# end
|
195
|
-
# end
|
196
|
-
# end
|
197
|
-
|
198
|
-
# class Param < Value
|
199
|
-
# def initialize(v)
|
200
|
-
# @value = value
|
201
|
-
# end
|
202
|
-
|
203
|
-
# def value
|
204
|
-
# @value
|
205
|
-
# end
|
206
|
-
# end
|
207
|
-
|
208
|
-
# class Method < Value
|
209
|
-
# attr_reader :name
|
210
|
-
# attr_reader :params
|
211
|
-
|
212
|
-
# def initialize(opts={})
|
213
|
-
# @name = opts[:name]
|
214
|
-
# @params = opts[:params]
|
215
|
-
# end
|
216
|
-
# end
|
217
|
-
|
218
|
-
class Bootstrap2Renderer < Redcarpet::Render::HTML
|
219
|
-
# alias_method :existing_block_code, :block_code
|
220
|
-
def block_code(code, language)
|
221
|
-
if language == "csv"
|
222
|
-
result = "<table class='table table-striped'>"
|
223
|
-
row_num = 0
|
224
|
-
CSV.parse(code) do |row|
|
225
|
-
if row_num == 0
|
226
|
-
result += "<thead><tr>#{row.collect { |c| "<th>#{c}</th>"}.join}</tr></thead>\n<tbody>\n"
|
227
|
-
else
|
228
|
-
result += "<tr>#{row.collect { |c| "<td>#{c}</td>"}.join}</tr>\n"
|
229
|
-
end
|
230
|
-
row_num += 1
|
231
|
-
end
|
232
|
-
result += "</tbody></table>"
|
233
|
-
elsif language == "formatted_json"
|
234
|
-
begin
|
235
|
-
obj = JSON.parse(code)
|
236
|
-
result = Pygments.highlight(JSON.pretty_generate(obj), lexer: "json")
|
237
|
-
rescue => e
|
238
|
-
result = Pygments.highlight(code, lexer: "json")
|
239
|
-
end
|
240
|
-
else
|
241
|
-
result = Pygments.highlight(code, lexer: language)
|
242
|
-
end
|
243
|
-
result
|
192
|
+
def output_lines
|
193
|
+
self.output.split("\n") if self.output
|
244
194
|
end
|
245
195
|
end
|
246
196
|
end
|
data/lib/markdownplus/version.rb
CHANGED
data/markdownplus.gemspec
CHANGED
@@ -0,0 +1,275 @@
|
|
1
|
+
require 'markdownplus'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Markdownplus::DirectiveParser do
|
5
|
+
context "a simple function with no params" do
|
6
|
+
let(:value) { Markdownplus::DirectiveParser.parse("include()") }
|
7
|
+
|
8
|
+
it "should return a TransformationLiteral" do
|
9
|
+
expect(value.class).to eq(Markdownplus::Literals::TransformationLiteral)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should have a single function" do
|
13
|
+
expect(value.functions.count).to eq(1)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should have a function named 'include'" do
|
17
|
+
expect(value.functions.first.function_name).to eq("include")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have no parameters" do
|
21
|
+
expect(value.functions.first.function_parameters.count).to eq(0)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "a simple function with a single param" do
|
26
|
+
let(:value) { Markdownplus::DirectiveParser.parse("include(test)") }
|
27
|
+
|
28
|
+
it "should return a TransformationLiteral" do
|
29
|
+
expect(value.class).to eq(Markdownplus::Literals::TransformationLiteral)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should have a single function" do
|
33
|
+
expect(value.functions.count).to eq(1)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should have a function named 'include'" do
|
37
|
+
expect(value.functions.first.function_name).to eq("include")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should have a single parameter" do
|
41
|
+
expect(value.functions.first.function_parameters.count).to eq(1)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should have the parameter 'test'" do
|
45
|
+
expect(value.functions.first.function_parameters.first.to_s).to eq("test")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
context "a simple function with a 3 params" do
|
49
|
+
let(:value) { Markdownplus::DirectiveParser.parse("include(test, 'this is a test', nil)") }
|
50
|
+
|
51
|
+
it "should return a TransformationLiteral" do
|
52
|
+
expect(value.class).to eq(Markdownplus::Literals::TransformationLiteral)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should have a single function" do
|
56
|
+
expect(value.functions.count).to eq(1)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should have a function named 'include'" do
|
60
|
+
expect(value.functions.first.function_name).to eq("include")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should have 3 parameters" do
|
64
|
+
expect(value.functions.first.function_parameters.count).to eq(3)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "the first parameter should be correct" do
|
68
|
+
expect(value.functions.first.function_parameters[0].class).to eq(Markdownplus::Literals::SymbolLiteral)
|
69
|
+
expect(value.functions.first.function_parameters[0].to_s).to eq("test")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "the second parameter should be correct" do
|
73
|
+
expect(value.functions.first.function_parameters[1].class).to eq(Markdownplus::Literals::StringLiteral)
|
74
|
+
expect(value.functions.first.function_parameters[1].to_s).to eq("this is a test")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "the third parameter should be correct" do
|
78
|
+
expect(value.functions.first.function_parameters[2].class).to eq(Markdownplus::Literals::SymbolLiteral)
|
79
|
+
expect(value.functions.first.function_parameters[2].to_s).to eq("nil")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "a series of two functions" do
|
84
|
+
let(:value) { Markdownplus::DirectiveParser.parse("include(), execute()") }
|
85
|
+
|
86
|
+
it "should return a TransformationLiteral" do
|
87
|
+
expect(value.class).to eq(Markdownplus::Literals::TransformationLiteral)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should have 2 functions" do
|
91
|
+
expect(value.functions.count).to eq(2)
|
92
|
+
end
|
93
|
+
|
94
|
+
context "the first function" do
|
95
|
+
let(:function) { value.functions[0] }
|
96
|
+
|
97
|
+
it "should be 'include'" do
|
98
|
+
expect(function.function_name).to eq("include")
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should have no parameters" do
|
102
|
+
expect(function.function_parameters.count).to eq(0)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "the second function" do
|
107
|
+
let(:function) { value.functions[1] }
|
108
|
+
|
109
|
+
it "should be 'include'" do
|
110
|
+
expect(function.function_name).to eq("execute")
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should have no parameters" do
|
114
|
+
expect(function.function_parameters.count).to eq(0)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "a function with a nested function" do
|
120
|
+
let(:value) { Markdownplus::DirectiveParser.parse("include(test, execute('nested test'))") }
|
121
|
+
|
122
|
+
it "should return a TransformationLiteral" do
|
123
|
+
expect(value.class).to eq(Markdownplus::Literals::TransformationLiteral)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should have a single function" do
|
127
|
+
expect(value.functions.count).to eq(1)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should have a function named 'include'" do
|
131
|
+
expect(value.functions.first.function_name).to eq("include")
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should have 2 parameters" do
|
135
|
+
expect(value.functions.first.function_parameters.count).to eq(2)
|
136
|
+
end
|
137
|
+
|
138
|
+
context "the second function parameter" do
|
139
|
+
let(:param) { value.functions.first.function_parameters[1] }
|
140
|
+
|
141
|
+
it "should be a functionLiteral" do
|
142
|
+
expect(param.class).to eq(Markdownplus::Literals::FunctionLiteral)
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should be a function named 'execute'" do
|
146
|
+
expect(param.function_name).to eq("execute")
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "a function with a url parameter" do
|
152
|
+
let(:value) { Markdownplus::DirectiveParser.parse("include('http://www.google.com')") }
|
153
|
+
|
154
|
+
it "should have a single function" do
|
155
|
+
expect(value.functions.count).to eq(1)
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should have a function named 'include'" do
|
159
|
+
expect(value.functions.first.function_name).to eq("include")
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should have 1 parameter" do
|
163
|
+
expect(value.functions.first.function_parameters.count).to eq(1)
|
164
|
+
end
|
165
|
+
|
166
|
+
context "the first parameter" do
|
167
|
+
let(:param) { value.functions.first.function_parameters.first }
|
168
|
+
|
169
|
+
it "should be google.com" do
|
170
|
+
expect(param.to_s).to eq("http://www.google.com")
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context "a function with parameters that contain strange characters" do
|
176
|
+
let(:value) { Markdownplus::DirectiveParser.parse("include('this-is_a @test', so_is-this)") }
|
177
|
+
|
178
|
+
it "should have a single function" do
|
179
|
+
expect(value.functions.count).to eq(1)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should have a function named 'include'" do
|
183
|
+
expect(value.functions.first.function_name).to eq("include")
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should have 2 parameters" do
|
187
|
+
expect(value.functions.first.function_parameters.count).to eq(2)
|
188
|
+
end
|
189
|
+
|
190
|
+
context "the first parameter" do
|
191
|
+
let(:param) { value.functions.first.function_parameters[0] }
|
192
|
+
|
193
|
+
it "should be correct" do
|
194
|
+
expect(param.to_s).to eq("this-is_a @test")
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context "the second parameter" do
|
199
|
+
let(:param) { value.functions.first.function_parameters[1] }
|
200
|
+
|
201
|
+
it "should be correct" do
|
202
|
+
expect(param.to_s).to eq("so_is-this")
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
context "some specific cases" do
|
208
|
+
context "value 1" do
|
209
|
+
let(:value) { Markdownplus::DirectiveParser.parse("julia(dataFrame('my_variable', get('my_variable'))),strip_whitespace(),raw()") }
|
210
|
+
|
211
|
+
it "should parse" do
|
212
|
+
expect(value.class).to eq(Markdownplus::Literals::TransformationLiteral)
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should have a three functions" do
|
216
|
+
expect(value.functions.count).to eq(3)
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should have a function named 'julia'" do
|
220
|
+
expect(value.functions.first.function_name).to eq("julia")
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should have 1 parameter" do
|
224
|
+
expect(value.functions.first.function_parameters.count).to eq(1)
|
225
|
+
end
|
226
|
+
|
227
|
+
context "the function parameter" do
|
228
|
+
let(:param) { value.functions.first.function_parameters.first }
|
229
|
+
|
230
|
+
it "should be a functionLiteral" do
|
231
|
+
expect(param.class).to eq(Markdownplus::Literals::FunctionLiteral)
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should be a function named 'dataFrame'" do
|
235
|
+
expect(param.function_name).to eq("dataFrame")
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should have 2 parameters" do
|
239
|
+
expect(param.function_parameters.count).to eq(2)
|
240
|
+
end
|
241
|
+
|
242
|
+
context "the first parameter" do
|
243
|
+
let(:param1) { param.function_parameters.first }
|
244
|
+
it "should be a String" do
|
245
|
+
expect(param1.class).to eq(Markdownplus::Literals::StringLiteral)
|
246
|
+
end
|
247
|
+
|
248
|
+
it "should equal 'my_variable'" do
|
249
|
+
expect(param1.to_s).to eq("my_variable")
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
context "the second parameter" do
|
254
|
+
let(:param2) { param.function_parameters[1] }
|
255
|
+
it "should be a functionLiteral" do
|
256
|
+
expect(param2.class).to eq(Markdownplus::Literals::FunctionLiteral)
|
257
|
+
end
|
258
|
+
it "should be a function named 'get'" do
|
259
|
+
expect(param2.function_name).to eq("get")
|
260
|
+
end
|
261
|
+
it "should have a parameter 'my_variable'" do
|
262
|
+
expect(param2.function_parameters.first.to_s).to eq("my_variable")
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context "value 2" do
|
269
|
+
let(:value) { Markdownplus::DirectiveParser.parse("sql('postgres://username1:password2@ec2-12-345-678-9.compute-1.amazonaws.com:1234/database'),set('my_variable'),empty()") }
|
270
|
+
it "should parse" do
|
271
|
+
expect(value.class).to eq(Markdownplus::Literals::TransformationLiteral)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|