drawght 0.1.0 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 776b1ea99f39fc1716543bd837504d10ca2648babb6e283c0bbf0dcc6db10b5f
4
- data.tar.gz: 0aa2b64aaa564b8194266ac18d37627ae384ba3cf4e39d7ad84a3a5c342ef36c
3
+ metadata.gz: 8a5dd8e8d4c11181d223311d1db2e25d8d6a9e7065289fb2ab40de86ce4fd054
4
+ data.tar.gz: c9698b4604f71e915915bc57ceefd595a21e36fa1969ea0d40e0f6fb907dbed9
5
5
  SHA512:
6
- metadata.gz: 73a0b217f9ba7ecca5aaad07a182bc9756714245bd12af06a75b288b781f62bbbb6cce10013dcbcce66cc4e7a3631f62c07ed7ea9a0a50edf4525eb29dd3fd45
7
- data.tar.gz: 96895069175bf3326d10e4a40f6276120043b650d77211ed00dca259c00f4ddedeaa2d28622c35a70c12e15c02a42db5e4dd1dbda936ae1d2398b3b8c092cf0b
6
+ metadata.gz: f0e6771bf26dbacaf3d3c62dbfa947e87beb639cdad189b3c068227940a1c6410a25de09a6632b450f3128d924f9a32e90ec99910dc5e1fec803abc93f016801
7
+ data.tar.gz: 201f2fb4ad4de65f40d79f50d97da5244d826a18718e4bec2c84ee3935247fc0f0be49e34cc98a1d7867bb418afc90650c8b3e2aa38442684ff29460265d2b53
data/CHANGELOG.yaml ADDED
@@ -0,0 +1,23 @@
1
+ - version: 1.0.0
2
+ date: 2025-12-03
3
+ summary:
4
+ The compiler has finished.
5
+ changes:
6
+ - New compiler process.
7
+ - Refined extension methods have been added.
8
+ - Test coverage.
9
+ - Syntax revision for nested values in collections.
10
+
11
+ - version: 0.2.0
12
+ date: 2024-08-30
13
+ summary:
14
+ Tests and tests.
15
+ changes:
16
+ - Tests have been added to test variables, objects and lists.
17
+
18
+ - version: 0.1.0
19
+ date: 2021-07-11
20
+ summary:
21
+ Work in progress! Syntax and compiler have been coded.
22
+ changes:
23
+ - Process variables, objects and lists.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright © 2021, Hallison Batista
1
+ Copyright © 2021-2024, Hallison Batista
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,211 +1,348 @@
1
- # Drawght
2
-
3
- Drawght is a data handler for texts without logical statements. The goal is
4
- to use a dataset (such as the subject of a text) to draft a document
5
- template. It can be considered a mini template processor.
6
-
7
- Data is accessed through `{}` braces, replaced by their respective values.
8
-
9
- Considering the following data:
10
-
11
- ```yaml
12
- title: Drawght is a very useful sketch
13
- author:
14
- name: Hallison Batista
15
- email: email@hallison.dev.br
16
- networks:
17
- - name: Github
18
- url: //github.com/hallison
19
- - name: Twitter
20
- url: //twitter.com/hallison
21
- creation-date: 2021-06-28
22
- publishing date: 2021-07-01
23
- references:
24
- - name: Mustache
25
- url: //mustache.github.io
26
- - name: Handlebars
27
- url: //handlebarsjs.com
28
- tags:
29
- - Template
30
- - Draft
31
- ```
32
-
33
- Note that the `creation-date` and `publishing date` fields are normally
34
- identified by the parser.
35
-
36
- In a template written in Markdown:
37
-
38
- ```markdown
39
- # {title}
40
-
41
- Drawght is a good tool for writing draft documents using datasets without
42
- logical statements.
43
-
44
- Written by {author.name} <{author.email}>, created in {creation-date},
45
- published in {publishing date} and tagged by {tags#1}.
46
-
47
- - [{author.networks:name}]({author.networks:url})
48
-
49
- Follow the news on [{author.networks#1.name}]({author.networks#1.url}).
50
-
51
- The syntax was inspired by:
52
-
53
- - [{references:name}]({references:url})
54
-
55
- Tags:
56
-
57
- - {tags} (tagged by {author.name}).
58
- ```
59
-
60
- The Drawght processing returns the following result:
61
-
62
- ```markdown
63
- # Drawght is a very useful sketch
64
-
65
- Drawght is a good tool for writing draft documents using datasets without
66
- logical statements.
67
-
68
- Written by Hallison Batista <email@hallison.dev.br>, created in 2021-06-28,
69
- published in 2021-07-01 and tagged by Template.
70
-
71
- - [Dev.to](//dev.to/hallison)
72
- - [Github](//github.com/hallison)
73
- - [Twitter](//twitter.com/hallison)
74
-
75
- Follow the news on [Dev.to](//dev.to/hallison).
76
-
77
- The syntax was inspired by:
78
-
79
- - [Mustache](//mustache.github.io)
80
- - [Handlebars](//handlebarsjs.com)
81
-
82
- Tags:
83
-
84
- - Template (tagged by Hallison Batista).
85
- - Draf (tagged by Hallison Batista).
86
- ```
87
-
88
- In a template written in HTML:
89
-
90
- ```html
91
- <h1>{title}</h1>
92
-
93
- <p>
94
- Drawght is a good tool for writing draft documents using datasets without
95
- logical statements.
96
- </p>
97
-
98
- <p>
99
- Written by <a href="mailto:{author.email}">{author.name}</a>, created
100
- published in {publishing date} and tagged by {tags#1}.
101
- </p>
102
-
103
- <ul>
104
- <li><a href="{author.networks:url}">{author.networks:name}</a></li>
105
- </ul>
106
-
107
- <p>
108
- Follow the news on <a href="{author.networks#1.url}">author.networks#1.name</a>.
109
- </p>
110
-
111
- <p>
112
- The syntax was inspired by:
113
- </p>
114
-
115
- <ul>
116
- <a href="{references:url}">{references:name}</a>
117
- </ul>
118
-
119
- <p>
120
- Tags:
121
- </p>
122
-
123
- <ul>
124
- <li>{tags} (tagged by {author.name}).</li>
125
- </ul>
126
- ```
127
-
128
- The Drawght processing returns the following result:
129
-
130
- ```html
131
- <h1>Drawght is a very useful sketch</h1>
132
-
133
- <p>
134
- Drawght is a good tool for writing draft documents using datasets without
135
- logical statements.
136
- </p>
137
-
138
- <p>
139
- Written by <a href="mailto:email@hallison.dev.br">Hallison Batista</a>,
140
- created published in 2021-07-01 and tagged by Template.
141
- </p>
142
-
143
- <ul>
144
- <li><a href="//dev.to/hallison">Dev.to</a></li>
145
- <li><a href="//github.com/hallison">Github</a></li>
146
- <li><a href="//twitter.com/hallison">Twitter</a></li>
147
- </ul>
148
-
149
- <p>
150
- Follow the news on <a href="//dev.to/hallison">Dev.to</a>.
151
- </p>
152
-
153
- <p>
154
- The syntax was inspired by:
155
- </p>
156
-
157
- <ul>
158
- <a href="//mustache.github.io">Mustache</a>
159
- <a href="//handlebarsjs.com">Handlebars</a>
160
- </ul>
161
-
162
- <p>
163
- Tags:
164
- </p>
165
-
166
- <ul>
167
- <li>Template (tagged by Hallison Batista).</li>
168
- <li>Draf (tagged by Hallison Batista).</li>
169
- </ul>
170
- ```
171
-
172
- ## Syntax
173
-
174
- Drawght has a simple syntax:
175
-
176
- - `{key}`: converts `key` to its respective value. If the value is a list, then
177
- the row will be replicated and converted with the respective values.
178
-
179
- - `{object.key}`: converts `key` to its respective value inside `object`,
180
- assuming the same behavior as `{key}`.
181
-
182
- - `{list:key}`: selects `list`, replicates the line for each item in the list,
183
- and converts `key` to its respective value contained in an object within
184
- `list`. The `list` key can also be accessed by `object.list`, just as `key`
185
- can also be accessed by `object.key` which will be converted following the
186
- same process in case it is a list.
187
-
188
- - `{list#n.key}`: selects item object `n` (from 1) from `list` and converts
189
- `key` to its respective value. The whole process is similar to `object.key`.
190
-
191
- ## License (MIT)
192
-
193
- ### Copyright (c) 2021, Hallison Batista
194
-
195
- Permission is hereby granted, free of charge, to any person obtaining a copy of
196
- this software and associated documentation files (the "Software"), to deal in
197
- the Software without restriction, including without limitation the rights to
198
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
199
- of the Software, and to permit persons to whom the Software is furnished to do
200
- so, subject to the following conditions:
201
-
202
- The above copyright notice and this permission notice shall be included in all
203
- copies or substantial portions of the Software.
204
-
205
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
206
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
207
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
208
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
209
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
210
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
211
- SOFTWARE.
1
+ # Drawght
2
+
3
+ Drawght is a data handler for texts without logical statements. The goal is
4
+ to use a dataset (such as the subject of a text) to draft a document
5
+ template. It can be considered a mini template processor.
6
+
7
+ Data is accessed through `{}` braces, replaced by their respective values.
8
+
9
+ Considering the following data:
10
+
11
+ ```yaml
12
+ title: Drawght is a very useful sketch
13
+ author:
14
+ name: Hallison Batista
15
+ email: email@hallison.dev.br
16
+ networks:
17
+ - name: Github
18
+ url: //github.com/hallison
19
+ - name: Twitter
20
+ url: //twitter.com/hallison
21
+ creation-date: 2021-06-28
22
+ publishing date: 2021-07-01
23
+ references:
24
+ - name: Mustache
25
+ url: //mustache.github.io
26
+ - name: Handlebars
27
+ url: //handlebarsjs.com
28
+ tags:
29
+ - Template
30
+ - Draft
31
+ ```
32
+
33
+ Note that the `creation-date` and `publishing date` fields are normally
34
+ identified by the parser.
35
+
36
+ In a template written in Markdown:
37
+
38
+ ```markdown
39
+ # {title}
40
+
41
+ Drawght is a good tool for writing draft documents using datasets without
42
+ logical statements.
43
+
44
+ Written by {author.name} <{author.email}>, created in {creation-date},
45
+ published in {publishing date} and tagged by {tags#1}.
46
+
47
+ - [{author.networks:name}]({author.networks:url})
48
+
49
+ Follow the news on [{author.networks#1.name}]({author.networks#1.url}).
50
+
51
+ The syntax was inspired by:
52
+
53
+ - [{references:name}]({references:url})
54
+
55
+ Tags:
56
+
57
+ - {tags} (tagged by {author.name}).
58
+ ```
59
+
60
+ The Drawght processing returns the following result:
61
+
62
+ ```markdown
63
+ # Drawght is a very useful sketch
64
+
65
+ Drawght is a good tool for writing draft documents using datasets without
66
+ logical statements.
67
+
68
+ Written by Hallison Batista <email@hallison.dev.br>, created in 2021-06-28,
69
+ published in 2021-07-01 and tagged by Template.
70
+
71
+ - [Dev.to](//dev.to/hallison)
72
+ - [Github](//github.com/hallison)
73
+ - [Twitter](//twitter.com/hallison)
74
+
75
+ Follow the news on [Dev.to](//dev.to/hallison).
76
+
77
+ The syntax was inspired by:
78
+
79
+ - [Mustache](//mustache.github.io)
80
+ - [Handlebars](//handlebarsjs.com)
81
+
82
+ Tags:
83
+
84
+ - Template (tagged by Hallison Batista).
85
+ - Draf (tagged by Hallison Batista).
86
+ ```
87
+
88
+ In a template written in HTML:
89
+
90
+ ```html
91
+ <h1>{title}</h1>
92
+
93
+ <p>
94
+ Drawght is a good tool for writing draft documents using datasets without
95
+ logical statements.
96
+ </p>
97
+
98
+ <p>
99
+ Written by <a href="mailto:{author.email}">{author.name}</a>, created
100
+ published in {publishing date} and tagged by {tags#1}.
101
+ </p>
102
+
103
+ <ul>
104
+ <li><a href="{author.networks:url}">{author.networks:name}</a></li>
105
+ </ul>
106
+
107
+ <p>
108
+ Follow the news on <a href="{author.networks#1.url}">author.networks#1.name</a>.
109
+ </p>
110
+
111
+ <p>
112
+ The syntax was inspired by:
113
+ </p>
114
+
115
+ <ul>
116
+ <a href="{references:url}">{references:name}</a>
117
+ </ul>
118
+
119
+ <p>
120
+ Tags:
121
+ </p>
122
+
123
+ <ul>
124
+ <li>{tags} (tagged by {author.name}).</li>
125
+ </ul>
126
+ ```
127
+
128
+ The Drawght processing returns the following result:
129
+
130
+ ```html
131
+ <h1>Drawght is a very useful sketch</h1>
132
+
133
+ <p>
134
+ Drawght is a good tool for writing draft documents using datasets without
135
+ logical statements.
136
+ </p>
137
+
138
+ <p>
139
+ Written by <a href="mailto:email@hallison.dev.br">Hallison Batista</a>,
140
+ created published in 2021-07-01 and tagged by Template.
141
+ </p>
142
+
143
+ <ul>
144
+ <li><a href="//dev.to/hallison">Dev.to</a></li>
145
+ <li><a href="//github.com/hallison">Github</a></li>
146
+ <li><a href="//twitter.com/hallison">Twitter</a></li>
147
+ </ul>
148
+
149
+ <p>
150
+ Follow the news on <a href="//dev.to/hallison">Dev.to</a>.
151
+ </p>
152
+
153
+ <p>
154
+ The syntax was inspired by:
155
+ </p>
156
+
157
+ <ul>
158
+ <a href="//mustache.github.io">Mustache</a>
159
+ <a href="//handlebarsjs.com">Handlebars</a>
160
+ </ul>
161
+
162
+ <p>
163
+ Tags:
164
+ </p>
165
+
166
+ <ul>
167
+ <li>Template (tagged by Hallison Batista).</li>
168
+ <li>Draf (tagged by Hallison Batista).</li>
169
+ </ul>
170
+ ```
171
+
172
+ ## Install
173
+
174
+ ```bash
175
+ gem install drawght
176
+ ```
177
+
178
+ ## Usage
179
+
180
+ ```ruby
181
+ require "drawght"
182
+
183
+ template = "{package.name} v{package.version}"
184
+ result = Drawght.compile template, {
185
+ package: {
186
+ name: "Drawght",
187
+ version: "1.0.0",
188
+ }
189
+ }
190
+
191
+ puts result
192
+ # Drawght v1.0.0
193
+ ```
194
+
195
+ ## Syntax
196
+
197
+ Drawght has a simple syntax:
198
+
199
+ - `{key}`: converts `key` to its respective value. If the value is a
200
+ collection, then the row will be replicated and converted with the respective
201
+ values.
202
+
203
+ - `{object.key}`: converts `key` to its respective value inside `object`,
204
+ assuming the same behavior as `{key}`.
205
+
206
+ - `{collection:key}`: selects `collection`, replicates the line for each item
207
+ in the collection, and converts `key` to its respective value contained in an
208
+ object within `collection`. The `collection` key can also be accessed by
209
+ `object.collection`, just as `key` can also be accessed by `object.key` which
210
+ will be converted following the same process in case it is a collection.
211
+
212
+ - `{collection#n.key}`: selects item object `n` (from 1) from `collection` and
213
+ converts `key` to its respective value. The whole process is similar to
214
+ `object.key`.
215
+
216
+ ## How it works
217
+
218
+ ### Variables and attributes
219
+
220
+ #### Definition
221
+
222
+ ```yaml
223
+ Author:
224
+ Name: John Scalzi
225
+
226
+ Protagonist: John Perry
227
+ ```
228
+
229
+ #### Usage
230
+
231
+ ```
232
+ {Protagonist}
233
+ {Author.Name}
234
+ ```
235
+
236
+ ### Collections
237
+
238
+ #### Definition
239
+
240
+ ```yaml
241
+ Book Titles:
242
+ - Old Man's War
243
+ - The Ghost Brigades
244
+ - The Last Colony
245
+
246
+ # Or
247
+
248
+ Books:
249
+ - Title: Old Man's War
250
+ - Title: The Ghost Brigades
251
+ - Title: The Last Colony
252
+ ```
253
+
254
+ #### Usage
255
+
256
+ For value sequencing.
257
+
258
+ ```
259
+ {Book Titles}
260
+ {Books:Title}
261
+ ```
262
+
263
+ For value straightly.
264
+
265
+ ```
266
+ {Book Titles#1}
267
+ {Book Titles#2}
268
+ {Book Titles#3}
269
+
270
+ {Books#1.Title}
271
+ {Books#2.Title}
272
+ {Books#3.Title}
273
+ ```
274
+
275
+ ### Nested collections
276
+
277
+ #### Definition
278
+
279
+ ```yaml
280
+ Books:
281
+ - Title: Old Man's War
282
+ ISBN: 0-7653-0940-8
283
+
284
+ - Title: The Ghost Brigades
285
+ ISBN: 0-7653-1502-5
286
+
287
+ - Title: The Last Colony
288
+ ISBN: 0-7653-1697-8
289
+
290
+ Series:
291
+ - Name: Old Man's War
292
+ Books:
293
+ - Title: Old Man's War
294
+ ISBN: 0-7653-0940-8
295
+
296
+ - Title: The Ghost Brigades
297
+ ISBN: 0-7653-1502-5
298
+
299
+ - Title: The Last Colony
300
+ ISBN: 0-7653-1697-8
301
+
302
+ - Name: Lock In
303
+ Books:
304
+ - Title: Lock In
305
+ ISBN: 978-0-7653-7586-5
306
+ - Title: Head On
307
+ ISBN: 978-0-7653-8891-9
308
+ ```
309
+
310
+ #### Usage
311
+
312
+ ```
313
+ {Books:Title}
314
+
315
+ {Books#1.Title}
316
+
317
+ {Series:Name}
318
+
319
+ {Series:Books:Title}
320
+
321
+ {Series#1.Name}
322
+
323
+ {Series#1.Books:Title}
324
+
325
+ {Series#2.Books#2.Title}
326
+ ```
327
+
328
+ ## License (MIT)
329
+
330
+ ### Copyright (c) 2021-2025, Hallison Batista
331
+
332
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
333
+ this software and associated documentation files (the "Software"), to deal in
334
+ the Software without restriction, including without limitation the rights to
335
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
336
+ of the Software, and to permit persons to whom the Software is furnished to do
337
+ so, subject to the following conditions:
338
+
339
+ The above copyright notice and this permission notice shall be included in all
340
+ copies or substantial portions of the Software.
341
+
342
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
343
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
344
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
345
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
346
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
347
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
348
+ SOFTWARE.
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Drawght
5
+
6
+ class Compiler
7
+ using Extensions
8
+
9
+ include Parser
10
+
11
+ attr_reader :template, :dataset, :result
12
+
13
+ def initialize template, dataset = nil
14
+ @template = template
15
+ @result = template.dup
16
+ @dataset = dataset.deep_stringify_keys! if dataset
17
+ end
18
+
19
+ def compile dataset
20
+ @dataset ||= dataset.deep_stringify_keys!
21
+ compile!
22
+ end
23
+
24
+ def compile!
25
+ convert
26
+ result
27
+ end
28
+
29
+ private
30
+
31
+ def convert
32
+ lines = template.lines.map do |line|
33
+ next line unless line.match? PLACEHOLDERS_PATTERN
34
+
35
+ mapping_placeholders_from line
36
+
37
+ newline = convert_straightly_placeholders_from line
38
+
39
+ convert_sequential_placeholders_from newline
40
+ end
41
+
42
+ result.replace lines.join
43
+ end
44
+
45
+ def convert_straightly_placeholders_from string
46
+ straightly_placeholders.reduce string.dup do |template, holding|
47
+ matter = dataset.ditch *pathkeys_from(holding)
48
+
49
+ converted = [matter].flatten.map do |value|
50
+ template.dup.gsub! holding.to_placeholder, value.to_s
51
+ end
52
+
53
+ template.replace converted.join
54
+ end
55
+ end
56
+
57
+ def convert_sequential_placeholders_from string
58
+ sequential_placeholders.reduce string.dup do |template, (attribute, mappings)|
59
+ matter = dataset.ditch *pathkeys_from(attribute)
60
+
61
+ converted = matter.map do |values|
62
+ mappings.inject template.dup do |partial, (holding, key)|
63
+ value = values.ditch(*pathkeys_from(key)) || key
64
+ partial.dup.gsub! holding.to_placeholder, value.to_s
65
+ end
66
+ end
67
+
68
+ template.replace converted.join
69
+ end
70
+ end
71
+ end
72
+
73
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Drawght
5
+ module Mapper
6
+
7
+ end
8
+ end
@@ -1,68 +1,88 @@
1
- class Drawght::Parser
2
- PREFIX, ATTRIBUTE, QUERY, ITEM, SUFFIX, = "{", ".", ":", "#", "}"
3
- KEY, LIST, INDEX = "(?<key>.*?)", "(?<list>.*?)", "(?<index>.*?)"
4
- EOL = /\r?\n/
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
5
3
 
6
- KEY_PATTERN = Regexp.new "#{PREFIX}#{KEY}#{SUFFIX}"
7
- LIST_PATTERN = Regexp.new "#{PREFIX}#{LIST}#{QUERY}#{KEY}#{SUFFIX}"
8
- ITEM_PATTERN = Regexp.new "#{LIST}#{ITEM}#{INDEX}([#{ATTRIBUTE}]#{KEY})?$"
4
+ module Drawght
5
+ module Parser
6
+ using Extensions
9
7
 
10
- def initialize(template)
11
- @template = template
12
- end
8
+ def pathkeys_from placeholder
9
+ path = case placeholder
10
+ when ATTRIBUTES_PATTERN then
11
+ path_keys_for_attribute placeholder
12
+ when QUERY_PATTERN then
13
+ path_keys_for_query placeholder
14
+ else
15
+ [placeholder]
16
+ end
13
17
 
14
- def parse(data)
15
- self.parse_keys(self.parse_queries(@template, data), data)
16
- end
18
+ path.flatten
19
+ end
20
+
21
+ def placeholders_from string
22
+ return [] unless string =~ PLACEHOLDERS_PATTERN
23
+
24
+ string.scan(PLACEHOLDERS_PATTERN).flatten
25
+ end
17
26
 
18
- def parse_queries(template, data)
19
- template.split(EOL).map do |line|
20
- result = line
21
- line.scan LIST_PATTERN do |(list, key)|
22
- value = value_from_key(list, data)
23
- if value && (value.kind_of? Array) && key
24
- partial = line.gsub("#{list}#{QUERY}", "")
25
- parsed_lines = value.map { |item| parse_template(partial, item) }
26
- result = result.gsub(line, parsed_lines.join("\n"))
27
+ def mapping_placeholders_from string
28
+ clear_placeholder_mappings!
29
+
30
+ placeholders_from(string).map do |placeholder|
31
+ if placeholder =~ QUERY_PATTERN
32
+ placeholder.scan %r/^(.*)#{QUERY}(.*)$/ do |pathkeys, attribute|
33
+ (sequential_placeholders[pathkeys] ||= {}).update placeholder => attribute
34
+ end
35
+ else
36
+ straightly_placeholders.add placeholder
27
37
  end
38
+
39
+ placeholder
28
40
  end
29
- result
30
- end.join("\n")
31
- end
41
+ end
32
42
 
33
- def parse_keys(template, data)
34
- template.split(EOL).map do |line|
35
- parse_template(line, data)
36
- end.join("\n");
37
- end
43
+ def straightly_placeholders
44
+ @straightly_placeholders ||= []
45
+ end
46
+
47
+ def sequential_placeholders
48
+ @sequential_placeholders ||= {}
49
+ end
38
50
 
39
- def parse_template(template, data)
40
- result = template
41
- template.scan KEY_PATTERN do |(key)|
42
- template_key = "#{PREFIX}#{key}#{SUFFIX}"
43
- value = value_from_key(key, data) || template_key
44
- if value.kind_of? Array
45
- result = value.map { |item| template.gsub(template_key, item) }.join("\n")
51
+ def replace_placeholders template, value
52
+ case value
53
+ when Hash
54
+ replace_placeholder_attributes_for template, value
55
+ when Array
56
+ replace_placeholder_collections_for template, value
46
57
  else
47
- result = result.gsub(template_key, value.to_s)
58
+ replace_placeholder_variables_from template, value
48
59
  end
49
60
  end
50
- result
51
- end
52
61
 
53
- private
62
+ private
63
+
64
+ def path_keys_for_attribute placeholder
65
+ placeholder.split(ATTRIBUTES_PATTERN).map do |item|
66
+ if item.to_s =~ QUERY_PATTERN
67
+ path_keys_for_query item
68
+ else
69
+ item.to_s =~ /^\d/ ? item.to_i - 1 : item unless item.to_s.empty?
70
+ end
71
+ end.compact
72
+ end
54
73
 
55
- def value_from_key(nested_key, data)
56
- item = nested_key.match ITEM_PATTERN
57
- if item
58
- list, index, key = item.captures
59
- index = index && (index.to_i)
60
- value = data.dig *list.split(ATTRIBUTE)
61
- if value && (value.kind_of? Array) && index
62
- key ? value[index - 1][key] : value[index - 1]
74
+ def path_keys_for_query placeholder
75
+ placeholder.gsub(QUERY, "#{QUERY}&#{QUERY}").split(QUERY_PATTERN).map do |item|
76
+ if item.to_s =~ ATTRIBUTES_PATTERN
77
+ path_keys_for_attribute item
78
+ else
79
+ item
80
+ end
63
81
  end
64
- else
65
- data.dig *nested_key.split(ATTRIBUTE)
82
+ end
83
+
84
+ def clear_placeholder_mappings!
85
+ straightly_placeholders.clear && sequential_placeholders.clear
66
86
  end
67
87
  end
68
88
  end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module Drawght
4
+ VERSION = "1.0.0"
5
+ RELEASE_DATE = "2025-12-03"
6
+ CHANGESET = [
7
+ "New compiler process.",
8
+ "Refined extension methods have been added.",
9
+ "Test coverage.",
10
+ "Syntax revision for nested values in collections.",
11
+ ]
12
+ end
data/lib/drawght.rb CHANGED
@@ -1,7 +1,78 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
1
4
  module Drawght
5
+ TOKENS = [
6
+ PREFIX = '{',
7
+ SUFFIX = '}',
8
+ ATTRIBUTE = '.',
9
+ ITEM = '#',
10
+ QUERY = ':',
11
+ ]
12
+
13
+ PLACEHOLDERS_PATTERN = Regexp.new "\\#{PREFIX}([^\\#{SUFFIX}]+)\\#{SUFFIX}"
14
+
15
+ ATTRIBUTES_PATTERN = Regexp.new "\\#{ATTRIBUTE}|\\#{ITEM}"
16
+ ATTRIBUTE_PATTERN = Regexp.new "\\#{ATTRIBUTE}"
17
+ ITEM_PATTERN = Regexp.new "\\#{ITEM}"
18
+ QUERY_PATTERN = Regexp.new "\\#{QUERY}"
19
+
20
+ PATH_PATTERN = Regexp.new "\\#{ATTRIBUTE}|\\#{ITEM}|\\#{QUERY}"
21
+
22
+ module Extensions
23
+ refine Hash do
24
+ def deep_stringify_keys!
25
+ transform_keys! do |key|
26
+ case value = fetch(key)
27
+ when Hash then value.deep_stringify_keys!
28
+ when Array then
29
+ value.map! do |item|
30
+ (item.is_a? Hash) ? item.deep_stringify_keys! : item
31
+ end
32
+ end
33
+
34
+ key.to_s
35
+ end
36
+
37
+ self
38
+ end
39
+
40
+ def ditch *pathkeys
41
+ if i = pathkeys.index('&')
42
+ list, subpath = pathkeys[0..i - 1], pathkeys[i + 1..-1]
43
+ dig(*list).map{ |item| item.ditch *subpath }
44
+ else
45
+ dig *pathkeys
46
+ end
47
+ rescue => error
48
+ error.message += "The pathkeys \"#{pathkeys.join ','}\" is a not valid path"
49
+ raise error
50
+ end
51
+ end
52
+
53
+ refine Array do
54
+ def add item
55
+ push item unless include? item
56
+ self
57
+ end
58
+ end
59
+
60
+ refine String do
61
+ def to_placeholder
62
+ "#{PREFIX}#{self}#{SUFFIX}"
63
+ end
64
+ end
65
+ end
66
+
2
67
  require_relative "drawght/parser"
68
+ require_relative "drawght/compiler"
69
+ require_relative "drawght/version"
70
+
71
+ def self.load_template(template)
72
+ Compiler.new template
73
+ end
3
74
 
4
- def self.new(template)
5
- Drawght::Parser.new template
75
+ def self.compile(template, data)
76
+ load_template(template).compile data
6
77
  end
7
78
  end
metadata CHANGED
@@ -1,34 +1,44 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drawght
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hallison Batista
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2021-07-11 00:00:00.000000000 Z
10
+ date: 2025-12-03 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: |
13
+ Drawght v1.0.0 (2025-12-03)
14
+
14
15
  Drawght is a data handler for texts without logical statements. The goal is
15
16
  to use a dataset (such as the subject of a text) to draft a document
16
17
  template. It can be considered a mini template processor.
18
+
19
+ Latest changes:
20
+
21
+ - New compiler process.
22
+ - Refined extension methods have been added.
23
+ - Test coverage.
24
+ - Syntax revision for nested values in collections.
17
25
  email: email@hallison.dev.br
18
26
  executables: []
19
27
  extensions: []
20
28
  extra_rdoc_files: []
21
29
  files:
30
+ - CHANGELOG.yaml
22
31
  - LICENSE
23
32
  - README.md
24
- - drawght.gemspec
25
33
  - lib/drawght.rb
34
+ - lib/drawght/compiler.rb
35
+ - lib/drawght/mapper.rb
26
36
  - lib/drawght/parser.rb
27
- homepage: https://github.com/drawght/drawght-ruby
37
+ - lib/drawght/version.rb
38
+ homepage: https://drawght.github.io
28
39
  licenses:
29
40
  - MIT
30
41
  metadata: {}
31
- post_install_message:
32
42
  rdoc_options: []
33
43
  require_paths:
34
44
  - lib
@@ -43,8 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
43
53
  - !ruby/object:Gem::Version
44
54
  version: '0'
45
55
  requirements: []
46
- rubygems_version: 3.1.2
47
- signing_key:
56
+ rubygems_version: 3.6.7
48
57
  specification_version: 4
49
58
  summary: Drawght parser implementation in Ruby.
50
59
  test_files: []
data/drawght.gemspec DELETED
@@ -1,30 +0,0 @@
1
- Gem::Specification.new do |spec|
2
- spec.name = "drawght"
3
- spec.summary = "Drawght parser implementation in Ruby."
4
- spec.authors = ["Hallison Batista"]
5
- spec.email = "email@hallison.dev.br"
6
- spec.homepage = "https://github.com/drawght/drawght-ruby"
7
- spec.version = %x(git describe --tags --abbrev=0)
8
- spec.date = %x(git log --format='%as' --max-count=1)
9
- spec.licenses = ["MIT"]
10
- spec.platform = Gem::Platform::RUBY
11
-
12
- spec.files = %x(git ls-files).split.reject do |out|
13
- ignore = out =~ /([MR]ake|Gem)file/ || out =~ /^\./
14
- ignore = ignore || out =~ /example\..*/
15
- ignore = ignore || out =~ %r{^doc/api} || out =~ %r{^test/.*}
16
- ignore
17
- end
18
-
19
- spec.test_files = spec.files.select do |path|
20
- path =~ %r{^test/.*}
21
- end
22
-
23
- spec.description = <<-end.gsub /^[ ]{4}/m, ""
24
- Drawght is a data handler for texts without logical statements. The goal is
25
- to use a dataset (such as the subject of a text) to draft a document
26
- template. It can be considered a mini template processor.
27
- end
28
-
29
- spec.require_paths = ["lib"]
30
- end