d-mark 0.1 → 0.2.0

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.
@@ -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