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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bee205ce9623266e9787eec60d991ddc1f3b99a3
4
- data.tar.gz: 490bbf23b2a0a0b8cb1767f6b7a542f38a749ba1
3
+ metadata.gz: a113f03eb0aba71874ec39fdb2eeeb53327da22a
4
+ data.tar.gz: 8a022441c7fb0ef0bb82b23d696e2d165f0e5193
5
5
  SHA512:
6
- metadata.gz: 13cabb5e530a7067fe5e665c883d42f1bf59208249e2fd2ef9fe49cf87cfa0dffa1974be4307769dbb862d51ba466403154e6bbbbf655a244a275d760b26bacd
7
- data.tar.gz: e65a20361865f63a70cf4de93fa27634dcf831ac4d966c64ccb146dabd03796e277b23fdb43dd7ebeef9fdde947f2c1d800e2afeb5710ebf79ec4d9231608bc9
6
+ metadata.gz: 9b67ee738116a651db12715abf33da46b4d9ab78425b30d801ca6c5398be45bbd2bcae3092b7e48566538ec98d7a6620063a94d2da4a3546342229b143f9e991
7
+ data.tar.gz: a61696ac50d227e5b90c652d3593d300a46a66bed352e852c26feb5951c88c639fed7e9af32e6c304cb520b7edfd0b37e5b8716fddbedea77acb151f8aac02e0
data/Gemfile CHANGED
@@ -2,6 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
+ gem 'codecov', require: false
5
6
  gem 'guard'
6
7
  gem 'guard-rake'
7
8
  gem 'rspec'
@@ -1,15 +1,19 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- d-mark (0.1.0)
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
@@ -1,5 +1,12 @@
1
1
  # D★Mark news
2
2
 
3
+ ## 1.0.0a1 (2016-02-20)
4
+
5
+ Fixes:
6
+
7
+ * Allowed document to begin with blank lines (#4)
8
+ * Ensured error is raised on incorrectly escaped attribute value (#5)
9
+
3
10
  ## 0.2 (2016-02-11)
4
11
 
5
12
  Fixes:
@@ -1,7 +1,10 @@
1
1
  = D★Mark
2
2
  Denis Defreyne <denis@stoneship.org>
3
3
 
4
- CAUTION: D★Mark is experimental — use at your own risk!
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::Parser::ElementNode
211
+ when DMark::ElementNode
209
212
  out << "<#{node.name}>"
210
213
  handle_children(node)
211
214
  out << "</#{node.name}>"
@@ -22,6 +22,5 @@ Gem::Specification.new do |s|
22
22
 
23
23
  s.required_ruby_version = '>= 2.1.0'
24
24
 
25
- s.add_runtime_dependency('treetop', '~> 1.4')
26
25
  s.add_development_dependency('bundler', '>= 1.11.2', '< 2.0')
27
26
  end
@@ -1,2 +1,3 @@
1
+ require_relative 'd-mark/element_node'
1
2
  require_relative 'd-mark/parser'
2
3
  require_relative 'd-mark/translator'
@@ -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
@@ -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
- if try_read_identifier_tail
165
- case peek_char
166
- when '['
167
- true
168
- when '.'
169
- advance
170
- [' ', "\n", nil].include?(peek_char)
171
- end
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 nil, "\n"
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 nil, "\n", ']', ','
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
@@ -1,3 +1,3 @@
1
1
  module DMark
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '1.0.0a1'.freeze
3
3
  end
@@ -5,7 +5,7 @@ class MyHTMLTranslator < DMark::Translator
5
5
  case node
6
6
  when String
7
7
  out << node
8
- when DMark::Parser::ElementNode
8
+ when DMark::ElementNode
9
9
  out << "<#{node.name}>"
10
10
  handle_children(node)
11
11
  out << "</#{node.name}>"
@@ -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
@@ -3,7 +3,7 @@ def parse(s)
3
3
  end
4
4
 
5
5
  def element(name, attributes, children)
6
- DMark::Parser::ElementNode.new(name, attributes, children)
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
@@ -1,2 +1,10 @@
1
1
  require 'rspec'
2
+
3
+ require 'simplecov'
4
+ SimpleCov.start
5
+ if ENV['CI'] == 'true'
6
+ require 'codecov'
7
+ SimpleCov.formatter = SimpleCov::Formatter::Codecov
8
+ end
9
+
2
10
  require 'd-mark'
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.2.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 00:00:00.000000000 Z
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: '0'
83
+ version: 1.3.1
95
84
  requirements: []
96
85
  rubyforge_project:
97
86
  rubygems_version: 2.5.2