d-mark 0.2.0 → 1.0.0a1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +14 -5
- data/NEWS.md +7 -0
- data/README.adoc +5 -2
- data/d-mark.gemspec +0 -1
- data/lib/d-mark.rb +1 -0
- data/lib/d-mark/element_node.rb +36 -0
- data/lib/d-mark/parser.rb +31 -85
- data/lib/d-mark/version.rb +1 -1
- data/samples/trivial.rb +1 -1
- data/spec/d-mark/element_node_spec.rb +54 -0
- data/spec/d-mark/parser_spec.rb +32 -1
- data/spec/d-mark/translator_spec.rb +45 -0
- data/spec/spec_helper.rb +8 -0
- metadata +7 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a113f03eb0aba71874ec39fdb2eeeb53327da22a
|
4
|
+
data.tar.gz: 8a022441c7fb0ef0bb82b23d696e2d165f0e5193
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b67ee738116a651db12715abf33da46b4d9ab78425b30d801ca6c5398be45bbd2bcae3092b7e48566538ec98d7a6620063a94d2da4a3546342229b143f9e991
|
7
|
+
data.tar.gz: a61696ac50d227e5b90c652d3593d300a46a66bed352e852c26feb5951c88c639fed7e9af32e6c304cb520b7edfd0b37e5b8716fddbedea77acb151f8aac02e0
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
d-mark (
|
5
|
-
treetop (~> 1.4)
|
4
|
+
d-mark (1.0.0a1)
|
6
5
|
|
7
6
|
GEM
|
8
7
|
remote: https://rubygems.org/
|
9
8
|
specs:
|
10
9
|
ast (2.2.0)
|
10
|
+
codecov (0.1.4)
|
11
|
+
json
|
12
|
+
simplecov
|
13
|
+
url
|
11
14
|
coderay (1.1.0)
|
12
15
|
diff-lcs (1.2.5)
|
16
|
+
docile (1.1.5)
|
13
17
|
ffi (1.9.10)
|
14
18
|
formatador (0.2.5)
|
15
19
|
guard (2.13.0)
|
@@ -24,6 +28,7 @@ GEM
|
|
24
28
|
guard-rake (1.0.0)
|
25
29
|
guard
|
26
30
|
rake
|
31
|
+
json (1.8.3)
|
27
32
|
listen (3.0.6)
|
28
33
|
rb-fsevent (>= 0.9.3)
|
29
34
|
rb-inotify (>= 0.9.7)
|
@@ -35,7 +40,6 @@ GEM
|
|
35
40
|
shellany (~> 0.0)
|
36
41
|
parser (2.3.0.4)
|
37
42
|
ast (~> 2.2)
|
38
|
-
polyglot (0.3.5)
|
39
43
|
powerpack (0.1.1)
|
40
44
|
pry (0.10.3)
|
41
45
|
coderay (~> 1.1.0)
|
@@ -67,17 +71,22 @@ GEM
|
|
67
71
|
unicode-display_width (~> 0.3)
|
68
72
|
ruby-progressbar (1.7.5)
|
69
73
|
shellany (0.0.1)
|
74
|
+
simplecov (0.11.2)
|
75
|
+
docile (~> 1.1.0)
|
76
|
+
json (~> 1.8)
|
77
|
+
simplecov-html (~> 0.10.0)
|
78
|
+
simplecov-html (0.10.0)
|
70
79
|
slop (3.6.0)
|
71
80
|
thor (0.19.1)
|
72
|
-
treetop (1.6.3)
|
73
|
-
polyglot (~> 0.3)
|
74
81
|
unicode-display_width (0.3.1)
|
82
|
+
url (0.3.2)
|
75
83
|
|
76
84
|
PLATFORMS
|
77
85
|
ruby
|
78
86
|
|
79
87
|
DEPENDENCIES
|
80
88
|
bundler (>= 1.11.2, < 2.0)
|
89
|
+
codecov
|
81
90
|
d-mark!
|
82
91
|
guard
|
83
92
|
guard-rake
|
data/NEWS.md
CHANGED
data/README.adoc
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
= D★Mark
|
2
2
|
Denis Defreyne <denis@stoneship.org>
|
3
3
|
|
4
|
-
|
4
|
+
image:http://img.shields.io/gem/v/d-mark.svg[Gem version, link="http://rubygems.org/gems/d-mark"]
|
5
|
+
image:http://img.shields.io/travis/ddfreyne/d-mark.svg[Build status, link="https://travis-ci.org/ddfreyne/d-mark"]
|
6
|
+
image:http://img.shields.io/codeclimate/github/ddfreyne/d-mark.svg[Code Climate, link="https://codeclimate.com/github/ddfreyne/d-mark"]
|
7
|
+
image:http://img.shields.io/codecov/c/github/ddfreyne/d-mark.svg[Code Coverage, link="https://codecov.io/github/ddfreyne/d-mark"]
|
5
8
|
|
6
9
|
_D★Mark_ is a language for marking up prose. It facilitates writing semantically meaningful text, without limiting itself to the semantics provided by HTML or Markdown.
|
7
10
|
|
@@ -205,7 +208,7 @@ class MyXMLLikeTranslator < DMark::Translator
|
|
205
208
|
case node
|
206
209
|
when String
|
207
210
|
out << node
|
208
|
-
when DMark::
|
211
|
+
when DMark::ElementNode
|
209
212
|
out << "<#{node.name}>"
|
210
213
|
handle_children(node)
|
211
214
|
out << "</#{node.name}>"
|
data/d-mark.gemspec
CHANGED
data/lib/d-mark.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
module DMark
|
2
|
+
class ElementNode
|
3
|
+
attr_reader :name
|
4
|
+
attr_reader :attributes
|
5
|
+
attr_reader :children
|
6
|
+
|
7
|
+
def initialize(name, attributes, children)
|
8
|
+
@name = name
|
9
|
+
@attributes = attributes
|
10
|
+
@children = children
|
11
|
+
end
|
12
|
+
|
13
|
+
def inspect
|
14
|
+
io = ''
|
15
|
+
io << 'Element(' << @name << ', '
|
16
|
+
if @attributes.any?
|
17
|
+
io << @attributes.inspect
|
18
|
+
io << ', '
|
19
|
+
end
|
20
|
+
io << @children.inspect
|
21
|
+
io << ')'
|
22
|
+
io
|
23
|
+
end
|
24
|
+
|
25
|
+
def ==(other)
|
26
|
+
case other
|
27
|
+
when ElementNode
|
28
|
+
@name == other.name &&
|
29
|
+
@children == other.children &&
|
30
|
+
@attributes == other.attributes
|
31
|
+
else
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/d-mark/parser.rb
CHANGED
@@ -13,41 +13,6 @@ module DMark
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
class ElementNode
|
17
|
-
attr_reader :name
|
18
|
-
attr_reader :attributes
|
19
|
-
attr_reader :children
|
20
|
-
|
21
|
-
def initialize(name, attributes, children)
|
22
|
-
@name = name
|
23
|
-
@attributes = attributes
|
24
|
-
@children = children
|
25
|
-
end
|
26
|
-
|
27
|
-
def inspect
|
28
|
-
io = ''
|
29
|
-
io << 'Element(' << @name << ', '
|
30
|
-
if @attributes.any?
|
31
|
-
io << @attributes.inspect
|
32
|
-
io << ', '
|
33
|
-
end
|
34
|
-
io << @children.inspect
|
35
|
-
io << ')'
|
36
|
-
io
|
37
|
-
end
|
38
|
-
|
39
|
-
def ==(other)
|
40
|
-
case other
|
41
|
-
when ElementNode
|
42
|
-
@name == other.name &&
|
43
|
-
@children == other.children &&
|
44
|
-
@attributes == other.attributes
|
45
|
-
else
|
46
|
-
false
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
16
|
attr_reader :pos
|
52
17
|
|
53
18
|
def initialize(input)
|
@@ -62,6 +27,17 @@ module DMark
|
|
62
27
|
def parse
|
63
28
|
res = []
|
64
29
|
|
30
|
+
loop do
|
31
|
+
break if eof?
|
32
|
+
|
33
|
+
blank_pos = try_read_blank_line
|
34
|
+
break unless blank_pos
|
35
|
+
|
36
|
+
@pos = blank_pos
|
37
|
+
@line_nr += 1
|
38
|
+
@col_nr = 0
|
39
|
+
end
|
40
|
+
|
65
41
|
loop do
|
66
42
|
break if eof?
|
67
43
|
res << read_block_with_children
|
@@ -161,14 +137,14 @@ module DMark
|
|
161
137
|
|
162
138
|
success =
|
163
139
|
if try_read_identifier_head
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
140
|
+
read_identifier_tail
|
141
|
+
|
142
|
+
case peek_char
|
143
|
+
when '['
|
144
|
+
true
|
145
|
+
when '.'
|
146
|
+
advance
|
147
|
+
[' ', "\n", nil].include?(peek_char)
|
172
148
|
end
|
173
149
|
end
|
174
150
|
|
@@ -186,24 +162,6 @@ module DMark
|
|
186
162
|
end
|
187
163
|
end
|
188
164
|
|
189
|
-
# FIXME: ugly and duplicated
|
190
|
-
def try_read_identifier_tail
|
191
|
-
res = ''
|
192
|
-
|
193
|
-
loop do
|
194
|
-
char = peek_char
|
195
|
-
case char
|
196
|
-
when 'a'..'z', '-', '0'..'9'
|
197
|
-
advance
|
198
|
-
res << char
|
199
|
-
else
|
200
|
-
break
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
res.to_s
|
205
|
-
end
|
206
|
-
|
207
165
|
def detect_indentation
|
208
166
|
indentation_chars = 0
|
209
167
|
pos = @pos
|
@@ -221,26 +179,6 @@ module DMark
|
|
221
179
|
indentation_chars / 2
|
222
180
|
end
|
223
181
|
|
224
|
-
def read_until_eol_or_eof
|
225
|
-
res = ''
|
226
|
-
|
227
|
-
loop do
|
228
|
-
char = peek_char
|
229
|
-
case char
|
230
|
-
when "\n"
|
231
|
-
advance
|
232
|
-
break
|
233
|
-
when nil
|
234
|
-
break
|
235
|
-
else
|
236
|
-
advance
|
237
|
-
res << char
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
res.to_s
|
242
|
-
end
|
243
|
-
|
244
182
|
def read_indentation(indentation)
|
245
183
|
indentation.times do
|
246
184
|
read_char(' ')
|
@@ -363,20 +301,28 @@ module DMark
|
|
363
301
|
|
364
302
|
if is_escaping
|
365
303
|
case char
|
366
|
-
when
|
367
|
-
break
|
368
|
-
else
|
304
|
+
when '%', ']', ','
|
369
305
|
advance
|
370
306
|
res << char
|
371
307
|
is_escaping = false
|
308
|
+
when nil
|
309
|
+
raise_parse_error('unexpected file end in attribute value')
|
310
|
+
when "\n"
|
311
|
+
raise_parse_error('unexpected line break in attribute value')
|
312
|
+
else
|
313
|
+
raise_parse_error(%(expected "%", "," or "]" after "%", but got #{char.inspect}))
|
372
314
|
end
|
373
315
|
else
|
374
316
|
case char
|
375
|
-
when
|
317
|
+
when ']', ','
|
376
318
|
break
|
377
319
|
when '%'
|
378
320
|
advance
|
379
321
|
is_escaping = true
|
322
|
+
when nil
|
323
|
+
raise_parse_error('unexpected file end in attribute value')
|
324
|
+
when "\n"
|
325
|
+
raise_parse_error('unexpected line break in attribute value')
|
380
326
|
else
|
381
327
|
advance
|
382
328
|
res << char
|
data/lib/d-mark/version.rb
CHANGED
data/samples/trivial.rb
CHANGED
@@ -0,0 +1,54 @@
|
|
1
|
+
describe DMark::ElementNode do
|
2
|
+
let(:element_node) { described_class.new(name, attributes, children) }
|
3
|
+
|
4
|
+
let(:name) { 'para' }
|
5
|
+
let(:attributes) { {} }
|
6
|
+
let(:children) { ['Hello!'] }
|
7
|
+
|
8
|
+
describe '#inspect' do
|
9
|
+
subject { element_node.inspect }
|
10
|
+
|
11
|
+
context 'no attributes' do
|
12
|
+
let(:attributes) { {} }
|
13
|
+
|
14
|
+
it { is_expected.to eql('Element(para, ["Hello!"])') }
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'attributes' do
|
18
|
+
let(:attributes) { { 'only' => 'web' } }
|
19
|
+
|
20
|
+
it { is_expected.to eql('Element(para, {"only"=>"web"}, ["Hello!"])') }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#==' do
|
25
|
+
subject { element_node == other }
|
26
|
+
|
27
|
+
context 'other is not an element node' do
|
28
|
+
let(:other) { 'donkey' }
|
29
|
+
it { is_expected.to be false }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'other is an element node' do
|
33
|
+
context 'other does not differ' do
|
34
|
+
let(:other) { described_class.new(name, attributes, children) }
|
35
|
+
it { is_expected.to be true }
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'other differs in name' do
|
39
|
+
let(:other) { described_class.new('giraffe', attributes, children) }
|
40
|
+
it { is_expected.to be false }
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'other differs in attributes' do
|
44
|
+
let(:other) { described_class.new(name, { 'friend' => 'donkey' }, children) }
|
45
|
+
it { is_expected.to be false }
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'other differs in children' do
|
49
|
+
let(:other) { described_class.new(name, attributes, []) }
|
50
|
+
it { is_expected.to be false }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/spec/d-mark/parser_spec.rb
CHANGED
@@ -3,7 +3,7 @@ def parse(s)
|
|
3
3
|
end
|
4
4
|
|
5
5
|
def element(name, attributes, children)
|
6
|
-
DMark::
|
6
|
+
DMark::ElementNode.new(name, attributes, children)
|
7
7
|
end
|
8
8
|
|
9
9
|
describe 'DMark::Parser#parser' do
|
@@ -260,6 +260,37 @@ describe 'DMark::Parser#parser' do
|
|
260
260
|
]
|
261
261
|
end
|
262
262
|
|
263
|
+
it 'parses document starting with blank lines' do
|
264
|
+
expect(parse(" \n \np. Hi!")).to eq [
|
265
|
+
element('p', {}, ['Hi!'])
|
266
|
+
]
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'does not parse percent escapes' do
|
270
|
+
expect { parse('p. %ref[url=https://github.com/pulls?q=is%3Aopen+user%3Ananoc]{eek}') }
|
271
|
+
.to raise_error(DMark::Parser::ParserError, 'parse error at line 1, col 43: expected "%", "," or "]" after "%", but got "3"')
|
272
|
+
end
|
273
|
+
|
274
|
+
it 'does not parse attribute values ending with an end-of-file' do
|
275
|
+
expect { parse('p. %ref[url=hello') }
|
276
|
+
.to raise_error(DMark::Parser::ParserError, 'parse error at line 1, col 18: unexpected file end in attribute value')
|
277
|
+
end
|
278
|
+
|
279
|
+
it 'does not parse attribute values ending with a line break' do
|
280
|
+
expect { parse("p. %ref[url=hello\n") }
|
281
|
+
.to raise_error(DMark::Parser::ParserError, 'parse error at line 1, col 18: unexpected line break in attribute value')
|
282
|
+
end
|
283
|
+
|
284
|
+
it 'does not parse escaped attribute values ending with an end-of-file' do
|
285
|
+
expect { parse('p. %ref[url=hello%') }
|
286
|
+
.to raise_error(DMark::Parser::ParserError, 'parse error at line 1, col 19: unexpected file end in attribute value')
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'does not parse escaped attribute values ending with a line break' do
|
290
|
+
expect { parse("p. %ref[url=hello%\n") }
|
291
|
+
.to raise_error(DMark::Parser::ParserError, 'parse error at line 1, col 19: unexpected line break in attribute value')
|
292
|
+
end
|
293
|
+
|
263
294
|
it 'does not parse' do
|
264
295
|
expect { parse('p') }.to raise_error(DMark::Parser::ParserError)
|
265
296
|
expect { parse('0') }.to raise_error(DMark::Parser::ParserError)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
describe DMark::Translator do
|
2
|
+
let(:translator) { translator_class.new(nodes) }
|
3
|
+
let(:translator_class) { described_class }
|
4
|
+
|
5
|
+
let(:nodes) do
|
6
|
+
[
|
7
|
+
DMark::ElementNode.new(
|
8
|
+
'para',
|
9
|
+
{ 'only' => 'web', 'animal' => 'donkey' },
|
10
|
+
['Hi!']
|
11
|
+
)
|
12
|
+
]
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#run' do
|
16
|
+
subject { translator.run }
|
17
|
+
|
18
|
+
context 'translator base class' do
|
19
|
+
it 'raises NotImplementedError' do
|
20
|
+
expect { subject }.to raise_error(NotImplementedError)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'custom translator' do
|
25
|
+
let(:translator_class) do
|
26
|
+
Class.new(described_class) do
|
27
|
+
def handle(node)
|
28
|
+
case node
|
29
|
+
when String
|
30
|
+
out << node
|
31
|
+
when DMark::ElementNode
|
32
|
+
out << "<#{node.name}"
|
33
|
+
out << node.attributes.map { |k, v| ' ' + [k, v].join('=') }.join
|
34
|
+
out << '>'
|
35
|
+
handle_children(node)
|
36
|
+
out << "</#{node.name}>"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it { is_expected.to eql('<para only=web animal=donkey>Hi!</para>') }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: d-mark
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0a1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Defreyne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-02-
|
11
|
+
date: 2016-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: treetop
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.4'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.4'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: bundler
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -64,13 +50,16 @@ files:
|
|
64
50
|
- d-mark.gemspec
|
65
51
|
- lib/d-mark.rb
|
66
52
|
- lib/d-mark/cli.rb
|
53
|
+
- lib/d-mark/element_node.rb
|
67
54
|
- lib/d-mark/parser.rb
|
68
55
|
- lib/d-mark/translator.rb
|
69
56
|
- lib/d-mark/version.rb
|
70
57
|
- samples/identifiers-and-patterns.dmark
|
71
58
|
- samples/trivial.dmark
|
72
59
|
- samples/trivial.rb
|
60
|
+
- spec/d-mark/element_node_spec.rb
|
73
61
|
- spec/d-mark/parser_spec.rb
|
62
|
+
- spec/d-mark/translator_spec.rb
|
74
63
|
- spec/spec_helper.rb
|
75
64
|
homepage: http://rubygems.org/gems/d-mark
|
76
65
|
licenses:
|
@@ -89,9 +78,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
89
78
|
version: 2.1.0
|
90
79
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
80
|
requirements:
|
92
|
-
- - "
|
81
|
+
- - ">"
|
93
82
|
- !ruby/object:Gem::Version
|
94
|
-
version:
|
83
|
+
version: 1.3.1
|
95
84
|
requirements: []
|
96
85
|
rubyforge_project:
|
97
86
|
rubygems_version: 2.5.2
|