d-mark 0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ p. I’m a %em{trivial} example!
@@ -0,0 +1,20 @@
1
+ require 'd-mark'
2
+
3
+ class MyHTMLTranslator < DMark::Translator
4
+ def handle(node)
5
+ case node
6
+ when String
7
+ out << node
8
+ when DMark::Parser::ElementNode
9
+ out << "<#{node.name}>"
10
+ handle_children(node)
11
+ out << "</#{node.name}>"
12
+ end
13
+ end
14
+ end
15
+
16
+ content = File.read('samples/trivial.dmark')
17
+ parser = DMark::Parser.new(content)
18
+ tree = parser.parse
19
+
20
+ puts MyHTMLTranslator.new(tree).run
@@ -0,0 +1,271 @@
1
+ def parse(s)
2
+ DMark::Parser.new(s).parse
3
+ end
4
+
5
+ def element(name, attributes, children)
6
+ DMark::Parser::ElementNode.new(name, attributes, children)
7
+ end
8
+
9
+ describe 'DMark::Parser#parser' do
10
+ it 'parses' do
11
+ expect(parse('')).to eq []
12
+ expect(parse('p.')).to eq [element('p', {}, [])]
13
+ expect(parse('p. hi')).to eq [element('p', {}, ['hi'])]
14
+ expect(parse('p. hi %%')).to eq [element('p', {}, ['hi ', '%'])]
15
+ expect(parse('p. hi %}')).to eq [element('p', {}, ['hi ', '}'])]
16
+ end
17
+
18
+ it 'parses escaped % in block' do
19
+ expect(parse('p. %%')).to eq [
20
+ element('p', {}, ['%'])
21
+ ]
22
+ end
23
+
24
+ it 'parses escaped } in block' do
25
+ expect(parse('p. %}')).to eq [
26
+ element('p', {}, ['}'])
27
+ ]
28
+ end
29
+
30
+ it 'parses escaped % in inline block' do
31
+ expect(parse('p. %foo{%%}')).to eq [
32
+ element(
33
+ 'p', {},
34
+ [
35
+ element('foo', {}, ['%'])
36
+ ]
37
+ )
38
+ ]
39
+ end
40
+
41
+ it 'parses escaped } in inline block' do
42
+ expect(parse('p. %foo{%}}')).to eq [
43
+ element(
44
+ 'p', {},
45
+ [
46
+ element('foo', {}, ['}'])
47
+ ])
48
+ ]
49
+ end
50
+
51
+ it 'parses block with text and element content' do
52
+ expect(parse('p. hi %em{ho}')).to eq [
53
+ element(
54
+ 'p', {}, [
55
+ 'hi ',
56
+ element('em', {}, ['ho'])
57
+ ]
58
+ )
59
+ ]
60
+ end
61
+
62
+ it 'parses block with text and element content, followed by newline' do
63
+ expect(parse("p. hi %em{ho}\n")).to eq [
64
+ element(
65
+ 'p', {}, [
66
+ 'hi ',
67
+ element('em', {}, ['ho'])
68
+ ]
69
+ )
70
+ ]
71
+ end
72
+
73
+ it 'parses children' do
74
+ expect(parse("p. hi %em{ho}\n p. child p")).to eq [
75
+ element(
76
+ 'p', {}, [
77
+ 'hi ',
78
+ element('em', {}, ['ho']),
79
+ element('p', {}, ['child p'])
80
+ ]
81
+ )
82
+ ]
83
+ end
84
+
85
+ it 'parses children multiple levels deep' do
86
+ expect(parse("p. hi %em{ho}\n p. child p\n p. subchild p")).to eq [
87
+ element(
88
+ 'p', {}, [
89
+ 'hi ',
90
+ element('em', {}, ['ho']),
91
+ element(
92
+ 'p', {}, [
93
+ 'child p',
94
+ element(
95
+ 'p', {}, [
96
+ 'subchild p'
97
+ ]
98
+ )
99
+ ]
100
+ )
101
+ ]
102
+ )
103
+ ]
104
+ end
105
+
106
+ it 'ignores blanks' do
107
+ expect(parse("p. foo\n \n p. bar\n \n\n p. qux")).to eq [
108
+ element(
109
+ 'p', {}, [
110
+ 'foo',
111
+ element(
112
+ 'p', {}, [
113
+ 'bar',
114
+ element(
115
+ 'p', {}, [
116
+ 'qux'
117
+ ]
118
+ )
119
+ ]
120
+ )
121
+ ]
122
+ )
123
+ ]
124
+ end
125
+
126
+ it 'reads multiple consecutive blocks' do
127
+ expect(parse("p. foo\np. bar")).to eq [
128
+ element('p', {}, ['foo']),
129
+ element('p', {}, ['bar'])
130
+ ]
131
+ end
132
+
133
+ it 'includes raw content' do
134
+ expect(parse("p. foo\n donkey")).to eq [
135
+ element('p', {}, %W(foo \n donkey))
136
+ ]
137
+ end
138
+
139
+ it 'includes raw content including initial indentation' do
140
+ expect(parse("p. foo\n donkey")).to eq [
141
+ element('p', {}, ['foo', "\n", ' donkey'])
142
+ ]
143
+ end
144
+
145
+ it 'includes raw content from multiple lines' do
146
+ expect(parse("p. foo\n donkey\n giraffe\n zebra\n")).to eq [
147
+ element('p', {}, ['foo', "\n", ' donkey', "\n", 'giraffe', "\n", ' zebra'])
148
+ ]
149
+ end
150
+
151
+ it 'includes empty lines in raw content' do
152
+ expect(parse("p. foo\n\n donkey\n\n giraffe\n")).to eq [
153
+ element('p', {}, ['foo', "\n", "\n", 'donkey', "\n", "\n", ' giraffe'])
154
+ ]
155
+ end
156
+
157
+ it 'does not include line break after empty block element and before data lines' do
158
+ expect(parse("p.\n donkey\n")).to eq [
159
+ element('p', {}, ['donkey'])
160
+ ]
161
+ end
162
+
163
+ it 'parses inline element in data lines' do
164
+ expect(parse("p.\n %emph{donkey}\n")).to eq [
165
+ element('p', {}, [
166
+ element('emph', {}, ['donkey'])
167
+ ])
168
+ ]
169
+ end
170
+
171
+ it 'parses empty attributes' do
172
+ expect(parse('p[]. hi')).to eq [
173
+ element('p', {}, ['hi'])
174
+ ]
175
+ end
176
+
177
+ it 'parses single attribute' do
178
+ expect(parse('p[foo=bar]. hi')).to eq [
179
+ element('p', { 'foo' => 'bar' }, ['hi'])
180
+ ]
181
+ end
182
+
183
+ it 'parses single value-less attribute' do
184
+ expect(parse('p[foo]. hi')).to eq [
185
+ element('p', { 'foo' => 'foo' }, ['hi'])
186
+ ]
187
+ end
188
+
189
+ it 'parses multiple attributes' do
190
+ expect(parse('p[foo=bar,qux=donkey]. hi')).to eq [
191
+ element('p', { 'foo' => 'bar', 'qux' => 'donkey' }, ['hi'])
192
+ ]
193
+ end
194
+
195
+ it 'parses multiple value-less attributes' do
196
+ expect(parse('p[foo,qux]. hi')).to eq [
197
+ element('p', { 'foo' => 'foo', 'qux' => 'qux' }, ['hi'])
198
+ ]
199
+ end
200
+
201
+ it 'parses escaped attributes' do
202
+ expect(parse('p[foo=%],bar=%%,donkey=%,]. hi')).to eq [
203
+ element('p', { 'foo' => ']', 'bar' => '%', 'donkey' => ',' }, ['hi'])
204
+ ]
205
+ end
206
+
207
+ it 'parses attributes in empty block' do
208
+ expect(parse("p[foo=bar].\n hi")).to eq [
209
+ element('p', { 'foo' => 'bar' }, ['hi'])
210
+ ]
211
+ end
212
+
213
+ it 'parses block start on next line properly' do
214
+ expect(parse("p.\n this is not a child block.")).to eq [
215
+ element('p', {}, ['this is not a child block.'])
216
+ ]
217
+ end
218
+
219
+ it 'parses block start on next line with spacey' do
220
+ expect(parse("p.\n foo.bar")).to eq [
221
+ element('p', {}, ['foo.bar'])
222
+ ]
223
+ end
224
+
225
+ it 'parses child block without content' do
226
+ expect(parse("ul.\n li.\n p. You can.")).to eq [
227
+ element(
228
+ 'ul', {},
229
+ [
230
+ element(
231
+ 'li', {},
232
+ [
233
+ element('p', {}, ['You can.'])
234
+ ]
235
+ )
236
+ ]
237
+ )
238
+ ]
239
+ end
240
+
241
+ it 'parses child block without content at end' do
242
+ expect(parse("ul.\n li.")).to eq [
243
+ element(
244
+ 'ul', {},
245
+ [
246
+ element('li', {}, [])
247
+ ]
248
+ )
249
+ ]
250
+ end
251
+
252
+ it 'parses child block with attributes' do
253
+ expect(parse("ul.\n li[foo].")).to eq [
254
+ element(
255
+ 'ul', {},
256
+ [
257
+ element('li', { 'foo' => 'foo' }, [])
258
+ ]
259
+ )
260
+ ]
261
+ end
262
+
263
+ it 'does not parse' do
264
+ expect { parse('p') }.to raise_error(DMark::Parser::ParserError)
265
+ expect { parse('0') }.to raise_error(DMark::Parser::ParserError)
266
+ expect { parse('p0') }.to raise_error(DMark::Parser::ParserError)
267
+ expect { parse('0.') }.to raise_error(DMark::Parser::ParserError)
268
+ expect { parse('p. %') }.to raise_error(DMark::Parser::ParserError)
269
+ expect { parse('p. }') }.to raise_error(DMark::Parser::ParserError)
270
+ end
271
+ end
@@ -0,0 +1,2 @@
1
+ require 'rspec'
2
+ require 'd-mark'
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: d-mark
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: 0.2.0
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-01-31 00:00:00.000000000 Z
11
+ date: 2016-02-11 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'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -37,29 +51,27 @@ executables: []
37
51
  extensions: []
38
52
  extra_rdoc_files:
39
53
  - LICENSE
40
- - README.md
54
+ - README.adoc
41
55
  - NEWS.md
42
56
  files:
43
57
  - Gemfile
44
58
  - Gemfile.lock
59
+ - Guardfile
45
60
  - LICENSE
46
61
  - NEWS.md
47
- - README.md
62
+ - README.adoc
48
63
  - Rakefile
49
64
  - d-mark.gemspec
50
- - lib/dmark.rb
51
- - lib/dmark/lexer.rb
52
- - lib/dmark/nodes.rb
53
- - lib/dmark/parser.rb
54
- - lib/dmark/tokens.rb
55
- - lib/dmark/translator.rb
56
- - lib/dmark/version.rb
65
+ - lib/d-mark.rb
66
+ - lib/d-mark/cli.rb
67
+ - lib/d-mark/parser.rb
68
+ - lib/d-mark/translator.rb
69
+ - lib/d-mark/version.rb
57
70
  - samples/identifiers-and-patterns.dmark
58
- - samples/identifiers-and-patterns.html
59
- - scripts/translate-to-html.rb
60
- - tasks/doc.rake
61
- - tasks/rubocop.rake
62
- - tasks/test.rake
71
+ - samples/trivial.dmark
72
+ - samples/trivial.rb
73
+ - spec/d-mark/parser_spec.rb
74
+ - spec/spec_helper.rb
63
75
  homepage: http://rubygems.org/gems/d-mark
64
76
  licenses:
65
77
  - MIT
@@ -67,7 +79,7 @@ metadata: {}
67
79
  post_install_message:
68
80
  rdoc_options:
69
81
  - "--main"
70
- - README.md
82
+ - README.adoc
71
83
  require_paths:
72
84
  - lib
73
85
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -82,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
94
  version: '0'
83
95
  requirements: []
84
96
  rubyforge_project:
85
- rubygems_version: 2.5.1
97
+ rubygems_version: 2.5.2
86
98
  signing_key:
87
99
  specification_version: 4
88
100
  summary: markup language for writing text
data/README.md DELETED
@@ -1,70 +0,0 @@
1
- D★Mark
2
- ======
3
-
4
- **Status:** experimental — use at your own risk!
5
-
6
- _D★Mark_ is a markup language for writing text.
7
-
8
- It is aimed at being able to write semantically meaningful text without limiting itself to the semantics provided by HTML or Markdown.
9
-
10
- ## Usage
11
-
12
- Handling a D★Mark file consists of three stages: lexing, parsing, and translating.
13
-
14
- The lexing stage converts the data into a stream of tokens. Construct a lexer with the data as input, and call `#run` to get the tokens, catching any `DMark::Lexer::LexerError`:
15
-
16
- begin
17
- tokens = DMark::Lexer.new(File.read(ARGV[0])).run
18
- rescue DMark::Lexer::LexerError => e
19
- $stderr.puts e.message_for_tty
20
- exit 1
21
- end
22
-
23
- The parsing stage converts the stream of tokens into a node tree. Construct a parser with the tokens as input, and call `#run` to get the tree.
24
-
25
- tree = DMark::Parser.new(tokens).run
26
-
27
- The translating stage is not the responsibility of D★Mark. A translator is part of the domain of the source text, and D★Mark only deals with syntax rather than semantics. A translator will run over the tree and convert it into something else (usually another string). To do so, handle each node type (`RootNode`, `TextNode`, `ElementNode`). For example, the following translator will convert the tree into something that resembles XML:
28
-
29
- class MyXMLLikeTranslator < DMark::Translator
30
- def handle(node)
31
- case node
32
- when DMark::Nodes::RootNode
33
- handle_children(node)
34
- when DMark::Nodes::TextNode
35
- out << node.text
36
- when DMark::Nodes::ElementNode
37
- out << "<#{node.name}>"
38
- handle_children(node)
39
- out << "</#{node.name}>"
40
- end
41
- end
42
- end
43
-
44
- result = MyXMLLikeTranslator.new(tree).run
45
- puts result
46
-
47
- ## Samples
48
-
49
- The `samples/` directory contains some sample D★Mark files. They can be converted to HTML by running the `scripts/translate-to-html.rb` Ruby script, passing in the name of the file. The resulting HTML will be printed to standard output. For example:
50
-
51
- ruby scripts/translate-to-html.rb samples/identifiers-and-patterns.dmark
52
-
53
- ## Format
54
-
55
- _D★Mark_ knows two constructs:
56
-
57
- * Block-level elements. For example:
58
-
59
- p. Patterns are used to find items and layouts based on their identifier. They come in three varieties.
60
-
61
- * Inline elements. For example:
62
-
63
- p. Identifiers come in two types: the %emph{full} type, new in Nanoc 4, and the %emph{legacy} type, used in Nanoc 3.
64
-
65
- Block-level elements can be nested. For example:
66
-
67
- ul.
68
- li. glob patterns
69
- li. regular expression patterns
70
- li. legacy patterns