d-mark 0.2.0 → 1.0.0a1
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/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
|