d-mark 1.0.0a2 → 1.0.0a3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +8 -8
- data/NEWS.md +8 -0
- data/README.adoc +1 -1
- data/Rakefile +0 -4
- data/d-mark.gemspec +1 -1
- data/lib/d-mark/parser.rb +1 -1
- data/lib/d-mark/translator.rb +42 -13
- data/lib/d-mark/version.rb +1 -1
- data/samples/test.rb +65 -0
- data/samples/trivial.dmark +1 -1
- data/spec/d-mark/parser_spec.rb +4 -3
- data/spec/d-mark/translator_spec.rb +74 -18
- metadata +5 -5
- data/lib/d-mark/cli.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1542c550fe7394de16bd088b2b0adc7bc369419
|
4
|
+
data.tar.gz: 6601aacc0e5d8c9b5aae40309b8802acef9652dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5775a149e72d08f1ca5f24b3a2fd9f1ce78084fc790d6aa562db07912d0d19d62de09b1e1c3ff66636465bcf657ffb063345ddb6fa52a5bbce3ac1e989a0a55
|
7
|
+
data.tar.gz: c91e5b502cb9950561c257ba6f765d04d5b125c6f7ce965b336f843561a864050fcd217adb2b658b37f05c5ffbb70a56f8ca410159eabc72811f2639d34f5e1e
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
d-mark (1.0.
|
4
|
+
d-mark (1.0.0a3)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -46,7 +46,7 @@ GEM
|
|
46
46
|
method_source (~> 0.8.1)
|
47
47
|
slop (~> 3.4)
|
48
48
|
rainbow (2.1.0)
|
49
|
-
rake (
|
49
|
+
rake (11.1.0)
|
50
50
|
rb-fsevent (0.9.7)
|
51
51
|
rb-inotify (0.9.7)
|
52
52
|
ffi (>= 0.5.0)
|
@@ -54,7 +54,7 @@ GEM
|
|
54
54
|
rspec-core (~> 3.4.0)
|
55
55
|
rspec-expectations (~> 3.4.0)
|
56
56
|
rspec-mocks (~> 3.4.0)
|
57
|
-
rspec-core (3.4.
|
57
|
+
rspec-core (3.4.4)
|
58
58
|
rspec-support (~> 3.4.0)
|
59
59
|
rspec-expectations (3.4.0)
|
60
60
|
diff-lcs (>= 1.2.0, < 2.0)
|
@@ -63,12 +63,12 @@ GEM
|
|
63
63
|
diff-lcs (>= 1.2.0, < 2.0)
|
64
64
|
rspec-support (~> 3.4.0)
|
65
65
|
rspec-support (3.4.1)
|
66
|
-
rubocop (0.
|
67
|
-
parser (>= 2.3.0.
|
66
|
+
rubocop (0.38.0)
|
67
|
+
parser (>= 2.3.0.6, < 3.0)
|
68
68
|
powerpack (~> 0.1)
|
69
69
|
rainbow (>= 1.99.1, < 3.0)
|
70
70
|
ruby-progressbar (~> 1.7)
|
71
|
-
unicode-display_width (~> 0.
|
71
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
72
72
|
ruby-progressbar (1.7.5)
|
73
73
|
shellany (0.0.1)
|
74
74
|
simplecov (0.11.2)
|
@@ -78,7 +78,7 @@ GEM
|
|
78
78
|
simplecov-html (0.10.0)
|
79
79
|
slop (3.6.0)
|
80
80
|
thor (0.19.1)
|
81
|
-
unicode-display_width (0.
|
81
|
+
unicode-display_width (1.0.2)
|
82
82
|
url (0.3.2)
|
83
83
|
|
84
84
|
PLATFORMS
|
@@ -94,4 +94,4 @@ DEPENDENCIES
|
|
94
94
|
rubocop
|
95
95
|
|
96
96
|
BUNDLED WITH
|
97
|
-
1.
|
97
|
+
1.12.5
|
data/NEWS.md
CHANGED
data/README.adoc
CHANGED
@@ -16,7 +16,7 @@ Here’s an example of D★Mark:
|
|
16
16
|
----
|
17
17
|
para. This a paragraph; an element in block form containing some text.
|
18
18
|
|
19
|
-
note[only=web]. This is a note that will %
|
19
|
+
note[only=web]. This is a note that will %em{only} show up on web.
|
20
20
|
----
|
21
21
|
|
22
22
|
For details, see the http://ddfreyne.github.io/d-mark/[D★Mark web page].
|
data/Rakefile
CHANGED
data/d-mark.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.rdoc_options = ['--main', 'README.adoc']
|
21
21
|
s.extra_rdoc_files = ['LICENSE', 'README.adoc', 'NEWS.md']
|
22
22
|
|
23
|
-
s.required_ruby_version = '>= 2.
|
23
|
+
s.required_ruby_version = '>= 2.2.0'
|
24
24
|
|
25
25
|
s.add_development_dependency('bundler', '>= 1.11.2', '< 2.0')
|
26
26
|
end
|
data/lib/d-mark/parser.rb
CHANGED
data/lib/d-mark/translator.rb
CHANGED
@@ -1,28 +1,57 @@
|
|
1
1
|
module DMark
|
2
2
|
class Translator
|
3
|
-
|
3
|
+
class UnhandledNode < StandardError
|
4
|
+
attr_reader :node
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
def initialize(node)
|
7
|
+
@node = node
|
8
|
+
end
|
9
|
+
|
10
|
+
def message
|
11
|
+
case @node
|
12
|
+
when String
|
13
|
+
'Unhandled string node'
|
14
|
+
when DMark::ElementNode
|
15
|
+
"Unhandled element node #{@node.name.inspect}"
|
16
|
+
else
|
17
|
+
"Unhandled node #{@node.inspect}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.translate(nodes, context = {})
|
23
|
+
new.translate(nodes, context)
|
24
|
+
end
|
7
25
|
|
8
|
-
|
26
|
+
def translate(nodes, context = {})
|
27
|
+
[nodes.map { |node| handle(node, context) }].flatten.join('')
|
9
28
|
end
|
10
29
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
30
|
+
def handle(node, context = {})
|
31
|
+
case node
|
32
|
+
when String
|
33
|
+
handle_string(node, context)
|
34
|
+
when DMark::ElementNode
|
35
|
+
handle_element(node, context)
|
36
|
+
else
|
37
|
+
raise ArgumentError, "Cannot handle #{node.class}"
|
14
38
|
end
|
15
|
-
@out
|
16
39
|
end
|
17
40
|
|
18
|
-
|
41
|
+
# @abstract
|
42
|
+
def handle_string(string, _context)
|
43
|
+
raise DMark::Translator::UnhandledNode.new(string)
|
44
|
+
end
|
19
45
|
|
20
|
-
|
21
|
-
|
46
|
+
# @abstract
|
47
|
+
def handle_element(element, _context)
|
48
|
+
raise DMark::Translator::UnhandledNode.new(element)
|
22
49
|
end
|
23
50
|
|
24
|
-
|
25
|
-
|
51
|
+
private
|
52
|
+
|
53
|
+
def handle_children(node, context)
|
54
|
+
node.children.map { |child| handle(child, context) }
|
26
55
|
end
|
27
56
|
end
|
28
57
|
end
|
data/lib/d-mark/version.rb
CHANGED
data/samples/test.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'd-mark'
|
2
|
+
|
3
|
+
module DMarkBook
|
4
|
+
module Translators
|
5
|
+
class HTML < DMark::Translator
|
6
|
+
def handle_string(node)
|
7
|
+
[html_escape(node)]
|
8
|
+
end
|
9
|
+
|
10
|
+
def handle_element(node, path)
|
11
|
+
case node.name
|
12
|
+
when 'p', 'dl', 'dt', 'dd', 'ol', 'ul', 'li', 'code', 'kbd', 'blockquote'
|
13
|
+
wrap(node.name) { handle_children(node, path) }
|
14
|
+
when 'h'
|
15
|
+
depth = path.count { |node| node.name == 'section' } + 1
|
16
|
+
wrap("h#{depth}") { handle_children(node, path) }
|
17
|
+
when 'section'
|
18
|
+
wrap('section', id: id_for_section(node)) { handle_children(node, path) }
|
19
|
+
when 'em'
|
20
|
+
wrap('em') { handle_children(node, path) }
|
21
|
+
when 'link'
|
22
|
+
wrap('a', href: node.attributes['target']) { handle_children(node, path) }
|
23
|
+
when 'listing'
|
24
|
+
wrap('pre') { wrap('code') { handle_children(node, path) } }
|
25
|
+
else
|
26
|
+
raise DMark::Translator::UnhandledNode.new(node)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def wrap(name, params = {})
|
31
|
+
params_string = params.map { |k, v| " #{k}=\"#{html_escape(v)}\"" }.join('')
|
32
|
+
["<#{name}#{params_string}>", yield, "</#{name}>"]
|
33
|
+
end
|
34
|
+
|
35
|
+
def html_escape(s)
|
36
|
+
s.gsub('&', '&').gsub('<', '<')
|
37
|
+
end
|
38
|
+
|
39
|
+
def id_for_section(node)
|
40
|
+
header = node.children.find { |c| c.name == 'h' }
|
41
|
+
text = header.children.join('')
|
42
|
+
text.downcase.gsub(/[^a-zA-Z-]/, '-')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class SpecialHTML < DMarkBook::Translators::HTML
|
49
|
+
def handle_element(node, depths)
|
50
|
+
case node.name
|
51
|
+
when 'firstterm', 'prompt', 'filename'
|
52
|
+
wrap('span', class: node.name) { handle_children(node, depths) }
|
53
|
+
when 'note', 'todo'
|
54
|
+
wrap('div', class: node.name) { handle_children(node, depths) }
|
55
|
+
else
|
56
|
+
super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
content = File.readlines('site/content/index.dmark').drop(4).join
|
62
|
+
parser = DMark::Parser.new(content)
|
63
|
+
tree = parser.parse
|
64
|
+
|
65
|
+
puts SpecialHTML.new.translate(tree)
|
data/samples/trivial.dmark
CHANGED
@@ -1 +1 @@
|
|
1
|
-
p
|
1
|
+
#p I’m a %em{trivial} example!
|
data/spec/d-mark/parser_spec.rb
CHANGED
@@ -44,7 +44,8 @@ describe 'DMark::Parser#parser' do
|
|
44
44
|
'p', {},
|
45
45
|
[
|
46
46
|
element('foo', {}, ['}'])
|
47
|
-
]
|
47
|
+
]
|
48
|
+
)
|
48
49
|
]
|
49
50
|
end
|
50
51
|
|
@@ -161,8 +162,8 @@ describe 'DMark::Parser#parser' do
|
|
161
162
|
end
|
162
163
|
|
163
164
|
it 'parses inline element in data lines' do
|
164
|
-
expect(parse("#p\n %
|
165
|
-
element('p', {}, [element('
|
165
|
+
expect(parse("#p\n %em{donkey}")).to eq [
|
166
|
+
element('p', {}, [element('em', {}, ['donkey'])])
|
166
167
|
]
|
167
168
|
end
|
168
169
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
describe DMark::Translator do
|
2
|
-
let(:translator) { translator_class.new
|
2
|
+
let(:translator) { translator_class.new }
|
3
3
|
let(:translator_class) { described_class }
|
4
4
|
|
5
5
|
let(:nodes) do
|
@@ -7,39 +7,95 @@ describe DMark::Translator do
|
|
7
7
|
DMark::ElementNode.new(
|
8
8
|
'para',
|
9
9
|
{ 'only' => 'web', 'animal' => 'donkey' },
|
10
|
-
[
|
10
|
+
[
|
11
|
+
DMark::ElementNode.new('em', {}, ['Hello']),
|
12
|
+
' world!'
|
13
|
+
]
|
11
14
|
)
|
12
15
|
]
|
13
16
|
end
|
14
17
|
|
15
|
-
|
16
|
-
subject { translator.run }
|
17
|
-
|
18
|
+
shared_examples 'translates' do
|
18
19
|
context 'translator base class' do
|
19
|
-
it 'raises
|
20
|
-
expect { subject }.to raise_error(
|
20
|
+
it 'raises error' do
|
21
|
+
expect { subject }.to raise_error(
|
22
|
+
DMark::Translator::UnhandledNode,
|
23
|
+
'Unhandled element node "para"'
|
24
|
+
)
|
21
25
|
end
|
22
26
|
end
|
23
27
|
|
24
28
|
context 'custom translator' do
|
25
29
|
let(:translator_class) do
|
26
30
|
Class.new(described_class) do
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
def handle_string(string, _context)
|
32
|
+
[string]
|
33
|
+
end
|
34
|
+
|
35
|
+
def handle_element(element, context)
|
36
|
+
[
|
37
|
+
"<#{element.name}",
|
38
|
+
element.attributes.map { |k, v| ' ' + [k, v].join('=') }.join,
|
39
|
+
'>',
|
40
|
+
handle_children(element, context),
|
41
|
+
"</#{element.name}>"
|
42
|
+
]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it { is_expected.to eql('<para only=web animal=donkey><em>Hello</em> world!</para>') }
|
48
|
+
|
49
|
+
context 'doing something with context' do
|
50
|
+
let(:translator_class) do
|
51
|
+
Class.new(described_class) do
|
52
|
+
def handle_string(string, context)
|
53
|
+
[string, " [parent=#{context[:kind]}]"]
|
54
|
+
end
|
55
|
+
|
56
|
+
def handle_element(element, context)
|
57
|
+
[
|
58
|
+
"<#{element.name}",
|
59
|
+
element.attributes.map { |k, v| ' ' + [k, v].join('=') }.join,
|
60
|
+
'>',
|
61
|
+
handle_children(element, context.merge(kind: element.name)),
|
62
|
+
"</#{element.name}>"
|
63
|
+
]
|
37
64
|
end
|
38
65
|
end
|
39
66
|
end
|
67
|
+
|
68
|
+
it { is_expected.to eql('<para only=web animal=donkey><em>Hello [parent=em]</em> world! [parent=para]</para>') }
|
40
69
|
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
shared_examples 'errors on unknown type' do
|
74
|
+
it 'raises' do
|
75
|
+
expect { subject }.to raise_error(
|
76
|
+
ArgumentError,
|
77
|
+
'Cannot handle Symbol'
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '.translate' do
|
83
|
+
subject { translator_class.translate(nodes) }
|
84
|
+
include_examples 'translates'
|
85
|
+
|
86
|
+
context 'unrecognised type' do
|
87
|
+
subject { translator_class.translate([:donkey]) }
|
88
|
+
include_examples 'errors on unknown type'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#translate' do
|
93
|
+
subject { translator.translate(nodes) }
|
94
|
+
include_examples 'translates'
|
41
95
|
|
42
|
-
|
96
|
+
context 'unrecognised type' do
|
97
|
+
subject { translator.translate([:donkey]) }
|
98
|
+
include_examples 'errors on unknown type'
|
43
99
|
end
|
44
100
|
end
|
45
101
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: d-mark
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.0a3
|
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-03
|
11
|
+
date: 2016-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -49,11 +49,11 @@ files:
|
|
49
49
|
- Rakefile
|
50
50
|
- d-mark.gemspec
|
51
51
|
- lib/d-mark.rb
|
52
|
-
- lib/d-mark/cli.rb
|
53
52
|
- lib/d-mark/element_node.rb
|
54
53
|
- lib/d-mark/parser.rb
|
55
54
|
- lib/d-mark/translator.rb
|
56
55
|
- lib/d-mark/version.rb
|
56
|
+
- samples/test.rb
|
57
57
|
- samples/trivial.dmark
|
58
58
|
- samples/trivial.rb
|
59
59
|
- spec/d-mark/element_node_spec.rb
|
@@ -74,7 +74,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
74
74
|
requirements:
|
75
75
|
- - ">="
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 2.
|
77
|
+
version: 2.2.0
|
78
78
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">"
|
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
82
|
version: 1.3.1
|
83
83
|
requirements: []
|
84
84
|
rubyforge_project:
|
85
|
-
rubygems_version: 2.
|
85
|
+
rubygems_version: 2.6.6
|
86
86
|
signing_key:
|
87
87
|
specification_version: 4
|
88
88
|
summary: markup language for writing text
|
data/lib/d-mark/cli.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require_relative '../d-mark'
|
2
|
-
|
3
|
-
data = File.read(ARGV[0]).strip
|
4
|
-
|
5
|
-
parser = DMark::Parser.new(data)
|
6
|
-
begin
|
7
|
-
before = Time.now
|
8
|
-
result = parser.parse
|
9
|
-
after = Time.now
|
10
|
-
result.each do |tree|
|
11
|
-
puts tree.inspect
|
12
|
-
puts
|
13
|
-
end
|
14
|
-
puts "parse duration: #{(after - before).to_f}s"
|
15
|
-
rescue => e
|
16
|
-
case e
|
17
|
-
when DMark::Parser::ParserError
|
18
|
-
line = data.lines[e.line_nr]
|
19
|
-
|
20
|
-
puts "\e[31mError:\e[0m #{e.message}}"
|
21
|
-
puts
|
22
|
-
puts line
|
23
|
-
puts "\e[31m" + ' ' * e.col_nr + '↑' + "\e[0m"
|
24
|
-
exit 1
|
25
|
-
else
|
26
|
-
raise e
|
27
|
-
end
|
28
|
-
end
|