reportinator 0.2.0 → 0.3.3

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +51 -7
  3. data/Gemfile.lock +10 -0
  4. data/README.md +113 -22
  5. data/app/reports/example.report.json +7 -3
  6. data/app/reports/multiplication.report.json +1 -1
  7. data/app/reports/multiplication_v2.report.json +15 -0
  8. data/data/schema/report_schema.json +76 -0
  9. data/docs/0_first_report.md +8 -8
  10. data/lib/reportinator/base.rb +2 -1
  11. data/lib/reportinator/config.rb +10 -0
  12. data/lib/reportinator/function.rb +5 -5
  13. data/lib/reportinator/functions/array/flatten.rb +12 -0
  14. data/lib/reportinator/functions/array/helper.rb +7 -1
  15. data/lib/reportinator/functions/array/join.rb +1 -1
  16. data/lib/reportinator/functions/array/range.rb +11 -0
  17. data/lib/reportinator/functions/array/snippet.rb +30 -0
  18. data/lib/reportinator/functions/array/string.rb +10 -0
  19. data/lib/reportinator/functions/string/number.rb +26 -4
  20. data/lib/reportinator/functions/string/variable.rb +4 -2
  21. data/lib/reportinator/helpers.rb +29 -0
  22. data/lib/reportinator/parsers/method.rb +5 -2
  23. data/lib/reportinator/parsers/value.rb +14 -13
  24. data/lib/reportinator/report/column.rb +25 -0
  25. data/lib/reportinator/report/loader.rb +71 -0
  26. data/lib/reportinator/report/report.rb +33 -0
  27. data/lib/reportinator/report/row.rb +42 -0
  28. data/lib/reportinator/report/template.rb +108 -0
  29. data/lib/reportinator/{report.rb → report_type.rb} +4 -1
  30. data/lib/reportinator/types/model.rb +10 -5
  31. data/lib/reportinator/types/preset.rb +23 -2
  32. data/lib/reportinator/version.rb +1 -1
  33. data/lib/reportinator.rb +21 -11
  34. metadata +30 -5
  35. data/lib/reportinator/loader.rb +0 -120
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94a9663b55f56092c18cbb75fd7832823c7f80a20404575e168ffc7ef3c9bdb0
4
- data.tar.gz: 367ffe4a9b45bbe04b8e5992d8495d4988bf590d81daee9f8959bba4b88013f7
3
+ metadata.gz: dacec3e0a6c1fa83b9d6ab56a73e89718ec8a05abc97faad0bffc8e1abfd06cf
4
+ data.tar.gz: 531551d591e30e5963bde825412f0611d4b2aacb899db8438c5e27e7bb6725df
5
5
  SHA512:
6
- metadata.gz: 0d0a1cc0db797d02d212d33ec8fcbb50127d9d5801a92bddf0544505f4ffe903ebb4230e48114cf067c62e73e89ca5f64b91f90261ef41682244780c65c09975
7
- data.tar.gz: 64de0d19db4a9bd0553de2abd6bd5426a5b68d4efdf872c7ec7a9ab353b9223bc2f0df6737fe5174a79f3a06d6c85091de172d75a42e5004ffb95694e22a6f82
6
+ metadata.gz: 7871de24cb6a5ee01b3d322c3eb1f608771fc295a465d17f9cb5b8972133f07b356f9f6d07303827828a1427f012a874b87bd1def683e3bcf54359d45ced25c4
7
+ data.tar.gz: 370375bb5373b1d84fdf26fde1fd92d449e09b65cc106645806796229f541c4c0491c11c139058e7c23b6712fbcf784bf10499a20bc4a35396a47ec539e04fce
data/CHANGELOG.md CHANGED
@@ -1,4 +1,48 @@
1
- ## [Unreleased]
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.3.3] 2022-11-28
9
+ ### Fixed
10
+ - Target parsed by ValueParser.parse_and_execute method no longer is duplicated
11
+ - This fixes a bug where active record relations would not properly function
12
+ - ValueParser.parse has now a third parameter, a boolean on whether to duplicate
13
+
14
+ ## [0.3.2] 2022-11-24
15
+ ### Fixed
16
+ - Reference to schema file
17
+
18
+ ## [0.3.1] 2022-11-24
19
+ ### Fixed
20
+ - Add "json_schemer" to gem dependencies
21
+
22
+ ## [0.3.0] 2022-11-24
23
+ ### Added
24
+ - Add template object
25
+ - Report types can opt in to parsing the data themselves
26
+ - Added "to_csv" method to report
27
+ - Added ">string" array function
28
+ - Added ">range" array function
29
+ - Added ">sum" array function
30
+ - Added "!nf" and "!ni" to convert a number to a float or integer
31
+ - Added "snippets"
32
+ - Added JSON Schema for report validation
33
+
34
+ ### Changed
35
+ - Preset report now takes in a "values" array, rather than a "data" array
36
+ - Refactor loader to be report loader
37
+ - "variables" have now been moved to be underneath the "metadata" tag.
38
+ - "metadata" is now passed to the Value parser instead of "variables"
39
+ - Re-ordered changelog to be latest change first
40
+ - Changelog now has KeepAChangelog info header
41
+
42
+ ### Fixed
43
+ - The Method function now works with non-string targets
44
+
45
+ ## [0.2.0] - 2022-10-14
2
46
  ### Added
3
47
  - Added parser for true, false and nil ("@true", "@false", "@nil")
4
48
  - Escape parsed methods and values starting with a special character
@@ -17,6 +61,11 @@
17
61
  - Method Parser no longer ignores empty and nil results.
18
62
  - Model report no longer double-parses values.
19
63
 
64
+ ## [0.1.1] - 2022-10-06
65
+ ### Fixed
66
+ - Move Base class to it's own file
67
+ - Now uses require_rel rather than require_all
68
+
20
69
  ## [0.1.0] - 2022-10-06
21
70
  - Initial release
22
71
 
@@ -25,9 +74,4 @@
25
74
  - Method parser
26
75
  - Preset report type
27
76
  - Model report type
28
- - Readme with report tutorial
29
-
30
- ## [0.1.1] - 2022-10-06
31
- ### Fixed
32
- - Move Base class to it's own file
33
- - Now uses require_rel rather than require_all
77
+ - Readme with report tutorial
data/Gemfile.lock CHANGED
@@ -18,9 +18,17 @@ GEM
18
18
  ast (2.4.2)
19
19
  concurrent-ruby (1.1.10)
20
20
  diff-lcs (1.5.0)
21
+ ecma-re-validator (0.4.0)
22
+ regexp_parser (~> 2.2)
23
+ hana (1.3.7)
21
24
  i18n (1.12.0)
22
25
  concurrent-ruby (~> 1.0)
23
26
  json (2.6.2)
27
+ json_schemer (0.2.23)
28
+ ecma-re-validator (~> 0.3)
29
+ hana (~> 1.3)
30
+ regexp_parser (~> 2.0)
31
+ uri_template (~> 0.7)
24
32
  minitest (5.16.3)
25
33
  parallel (1.22.1)
26
34
  parser (3.1.2.1)
@@ -65,11 +73,13 @@ GEM
65
73
  tzinfo (2.0.5)
66
74
  concurrent-ruby (~> 1.0)
67
75
  unicode-display_width (2.3.0)
76
+ uri_template (0.7.0)
68
77
 
69
78
  PLATFORMS
70
79
  x86_64-linux
71
80
 
72
81
  DEPENDENCIES
82
+ json_schemer (~> 0.2)
73
83
  rake (~> 13.0)
74
84
  reportinator!
75
85
  rspec (~> 3.0)
data/README.md CHANGED
@@ -50,19 +50,33 @@ A Report template has four attributes:
50
50
  | key | type | description |
51
51
  |-----------|--------|----------------------------------------------------|
52
52
  | type | symbol | specifies the report type to use |
53
- | variables | hash | defines variables to be used with the `$` function |
54
53
  | template | string | references another template to load and merge with |
54
+ | metadata | hash | values accessible to parser functions |
55
55
  | params | hash | report specific parameters |
56
56
 
57
- #### Reportinator String Function Cheatsheet
57
+ Values in report templates are passed through the value parser.
58
+ There are two main types of functions that can be parsed. String functions, and
59
+ array functions.
60
+
61
+ String functions return a value based on the contents of a string input.
62
+ They are useful for quick conversions, and simple functions.
63
+
64
+ Array functions return a value based on the contents of an array.
65
+ They are used for more complex functions, as more can be expressed with them.
66
+ The values in an array function are usually also parsed, although it is at the discretion
67
+ of the function do so.
68
+
69
+ #### String Function Cheatsheet
58
70
  | prefix | example | output |
59
71
  |---------|-----------------------------|--------------------------------------------|
60
72
  | `:` | ":symbol" | :symbol |
61
73
  | `&` | "&Constant" | Constant |
62
- | `$` | "$variable" | Value of key `variable` in variables hash. |
74
+ | `$` | "$variable" | Value `variable` in variables metadata. |
63
75
  | `!a` | "!a 1,2,3" | 6 |
64
76
  | `!d` | "!d 1970-01-01" | 1970-01-01 00:00:00 |
65
77
  | `!n` | "!n 100" | 100 |
78
+ | `!ni` | "!ni 103.34" | 103 |
79
+ | `!nf` | "!nf 103" | 103.0 |
66
80
  | `!j` | "!j 1,2,3" | "123" |
67
81
  | `!r` | "!r a,z" | ("a".."z") |
68
82
  | `!rd` | "!rd 1970-01-01,1979-01-01" | (1970-01-01 00:00:00..1979-01-01 00:00:00) |
@@ -72,9 +86,9 @@ A Report template has four attributes:
72
86
  | `@nil` | "@nil" | nil |
73
87
  | `@null` | "@null" | nil |
74
88
 
75
- #### Reportinator Array Function Cheatsheet
76
- When an array has a string as it's first value, and that string has a certain prefix
77
- the array is parsed as an Array Function.
89
+ #### Array Function Cheatsheet
90
+ When an array has a string as it's first value, and that string has a certain prefix,
91
+ the given array is parsed as an Array Function.
78
92
 
79
93
  Array functions have a target, then an array of values. Often, the values will work
80
94
  with the target to achieve an outcome.
@@ -95,7 +109,8 @@ are parsed, and sent as methods to it. The result is returned.
95
109
  This array is equivalent to running `Date.today.to_s`.
96
110
 
97
111
  Optionally, the prefix can be put on it's own, with no additional values
98
- after it.
112
+ after it. The second value, in this case "&Date", will become the target
113
+ instead.
99
114
  ```
100
115
  ["#", "&Date", ":today", ":to_s"]
101
116
  ```
@@ -106,13 +121,76 @@ to be more flexible, as it no longer has to be resolved from a string.
106
121
  ```
107
122
  This array is equally valid, and still returns the same result.
108
123
 
109
- prefix | example | ruby equivalent |
110
- -----------|------------------------------------------------|-----------------------------------------|
111
- `#` | `["#&Date", ":today"]` | Date.today |
112
- `>join` | `[">join", " - ", "a", "b", "c"]` | ["a", "b", "c"].join(" - ") |
113
- `>strf` | `[">strf", ["#&Date", ":today"], "%b, %Y"]` | Date.today.strftime("%b, %Y") |
114
- `>offset` | `[">offset $time", 2, ":month", ":end"]` | $time.advance(month: 2).at_end_of_month |
115
- `>title` | `[">title", "hello", "world"]` | ["hello", "world"].join(" ").titleize |
124
+ | prefix | example | ruby equivalent |
125
+ |-----------|------------------------------------------------|-----------------------------------------|
126
+ | `#` | `["#&Date", ":today"]` | Date.today |
127
+ | `>join` | `[">join", " - ", "a", "b", "c"]` | ["a", "b", "c"].join(" - ") |
128
+ | `>strf` | `[">strf", ["#&Date", ":today"], "%b, %Y"]` | Date.today.strftime("%b, %Y") |
129
+ | `>offset` | `[">offset $time", 2, ":month", ":end"]` | $time.advance(month: 2).at_end_of_month |
130
+ | `>title` | `[">title", "hello", "world"]` | ["hello", "world"].join(" ").titleize |
131
+ | `>snippet`| `[">snippet :test", {"var1": "hi"}]` | *See snippets section* |
132
+
133
+
134
+ ### Metadata
135
+ Metadata is defined in the "metadata" field of the template, and can be used by Parser Functions.
136
+ Metadata is merged from parent to child report template. Child metadata takes precedence over parent.
137
+
138
+ Reportinator's built in Parser Functions use two metadata fields; "variables", and "snippets".
139
+
140
+ #### Variables
141
+ Variables are values that can be accessed with the "$" string function.
142
+
143
+ ```
144
+ "metadata": {
145
+ "variables": {
146
+ "key": "value"
147
+ }
148
+ }
149
+ ```
150
+ ```
151
+ > Reportinator.parse "$key"
152
+ => "value"
153
+ ```
154
+
155
+ Variable values are also parsed, and themselves can even reference variables from parent templates.
156
+
157
+ ```
158
+ # $date = 1970-01-01
159
+ "metadata": {
160
+ "variables": {
161
+ "formatted_date": [">strf", "$date", "%b %d, %Y"]
162
+ }
163
+ }
164
+ ```
165
+ ```
166
+ > Reportinator.parse "$formatted_date"
167
+ => "Jan 01, 1970"
168
+ ```
169
+
170
+ #### Snippets
171
+ Snippets are values that are not parsed until called from the ">snippet" array function,
172
+ as opposed to variables, which are parsed before they are able to be called.
173
+
174
+ Snippets can be passed variables with a hash in the first value of the array function.
175
+
176
+ Example:
177
+ ```
178
+ "metadata": {
179
+ "snippets": {
180
+ "plus_10": [">sum", "$var", 10]
181
+ }
182
+ }
183
+ ```
184
+ ```
185
+ > Reportinator.parse [">snippet :plus_10", { "var": 5 }]
186
+ => 15
187
+ ```
188
+
189
+ Snippets help to reduce repetition of complex functionality in a report.
190
+ However, if a report is getting unwieldy with complex values to parse, it might
191
+ be a good idea to write a Custom Parser Function, or to write it into a method
192
+ on a class, and call it from a "&Constant". See the next section for setting up
193
+ custom functions.
116
194
 
117
195
  ### Configuring Reportinator
118
196
  ```
@@ -135,16 +213,27 @@ of the reports.
135
213
  ### Making a Custom Report Type
136
214
  The requirements to make a Report are very simple.
137
215
  1. The report must inherit from `Reportinator::Report`
138
- 2. The report must provide a `data` method, which returns a one or two dimensional array.
216
+ 2. The report should provide some attributes, to be set with the "params" field,
217
+ 3. The report must provide a `data` method, which returns either a Reportinator::Row,
218
+ or an array of them.
139
219
 
140
- For example, this is the entire code for the Preset Report:
220
+ Here's an example of a basic report type:
141
221
  ```
142
- module Reportinator
143
- class PresetReport < Report
144
- attribute :data, default: []
145
- end
222
+ class BasicReport < Reportinator::Report
223
+ attribute :values, default: []
224
+
225
+ def data
226
+ Reportinator::Row.create(values)
227
+ end
146
228
  end
147
229
  ```
230
+
231
+ `Reportinator::Row.create` takes in an array, and turns it into a Row.
232
+ For more fine-grained control, an instance of a Row can have data
233
+ inserted into it with the `insert` method. `insert` takes any data, then
234
+ a position, being either :first, :last, or an index number, to indicate where in
235
+ the row the data should be inserted.
236
+
148
237
  Once a report has been written, it must be registed as a report type.
149
238
  See the configuration section for more details.
150
239
 
@@ -155,11 +244,13 @@ or "Reportinator::ArrayFunction"
155
244
  2. The function must have a PREFIXES constant, with an array of the prefixes it'll accept.
156
245
  3. The function must provide an `output` method
157
246
 
158
- String functions gain access to two variables:
247
+ All functions have access to the `metadata` variable.
248
+
249
+ String functions gain access to two additional variables:
159
250
  - `prefix`, the prefix that the string used
160
251
  - `body`, the rest of the string with the prefix removed
161
252
 
162
- Array functions gain access to three variables:
253
+ Array functions gain access to three additional variables:
163
254
  - `prefix`, the prefix that was used
164
255
  - `target`, the first value after the prefix
165
256
  - `values`, the rest of the values, with the target removed
@@ -1,9 +1,13 @@
1
1
  [
2
2
  {
3
3
  "type": ":preset",
4
- "variables": {"variable": "i am a variable"},
4
+ "metadata": {
5
+ "variables": {
6
+ "variable": "i am a variable"
7
+ }
8
+ },
5
9
  "params": {
6
- "data": [
10
+ "values": [
7
11
  "string", ":symbol", "&Reportinator",
8
12
  "$variable", "!i 1234", "!a !i 2, 2",
9
13
  ["#!d 1970-01-01", {"strftime": "%b, %Y"}], "!r !i 1, !i 5"
@@ -13,7 +17,7 @@
13
17
  {
14
18
  "type": ":model",
15
19
  "params": {
16
- "target": ["#&Reportinator", ":config"],
20
+ "target": ["#", "&Reportinator", ":config"],
17
21
  "method_list": [":configured_directories", ":configured_suffixes", ":configured_types"]
18
22
  }
19
23
  }
@@ -2,7 +2,7 @@
2
2
  {
3
3
  "type": ":preset",
4
4
  "params": {
5
- "data": ["nx1","nx2","nx3","nx4","nx5"]
5
+ "values": ["nx1","nx2","nx3","nx4","nx5"]
6
6
  }
7
7
  },
8
8
  {
@@ -0,0 +1,15 @@
1
+ [
2
+ {
3
+ "type": ":preset",
4
+ "params": {
5
+ "values": ["5x5","nx1","nx2","nx3","nx4","nx5"]
6
+ }
7
+ },
8
+ {
9
+ "type": ":model",
10
+ "params": {
11
+ "target": "!rn 1,5",
12
+ "method_list": [[">join", "x", "$target", "n"],{"*": 1},{"*": 2},{"*": 3},{"*": 4},{"*": 5}]
13
+ }
14
+ }
15
+ ]
@@ -0,0 +1,76 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://moxvallix.com/meta/reportinator/report_schema.json",
4
+ "title": "Report",
5
+ "description": "A Reportinator Report",
6
+ "type": ["array", "object"],
7
+ "$defs": {
8
+ "template": {
9
+ "type": "object",
10
+ "properties": {
11
+ "type": {
12
+ "type": ["string", "array"]
13
+ },
14
+ "template": {
15
+ "type": ["string", "array"]
16
+ },
17
+ "metadata": {
18
+ "type": "object",
19
+ "properties": {
20
+ "snippets": {
21
+ "type": "object"
22
+ },
23
+ "variables": {
24
+ "type": "object"
25
+ }
26
+ }
27
+ },
28
+ "params": {
29
+ "type": "object"
30
+ }
31
+ },
32
+ "oneOf": [
33
+ {
34
+ "required": ["type"]
35
+ },
36
+ {
37
+ "required": ["template"]
38
+ }
39
+ ],
40
+ "allOf": [
41
+ {
42
+ "if": {
43
+ "properties": { "type": { "const": ":preset" } }
44
+ },
45
+ "then": {
46
+ "properties": { "params": { "properties": { "values": { "type": "array" } } } }
47
+ }
48
+ },
49
+ {
50
+ "if": {
51
+ "properties": { "type": { "const": ":model" } }
52
+ },
53
+ "then": {
54
+ "properties": {
55
+ "params": {
56
+ "properties": {
57
+ "target": { "type": ["string", "array"] },
58
+ "method_list": { "type": "array" }
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
64
+ ]
65
+ }
66
+ },
67
+ "if": {
68
+ "type": "object"
69
+ },
70
+ "then": {
71
+ "$ref": "#/$defs/template"
72
+ },
73
+ "else": {
74
+ "properties": { "items": { "$ref": "#/$defs/template" } }
75
+ }
76
+ }
@@ -31,7 +31,7 @@ Add "data" to a "params" object, and set it to be an empty array.
31
31
  {
32
32
  "type": ":preset",
33
33
  "params": {
34
- "data": []
34
+ "values": []
35
35
  }
36
36
  }
37
37
  ```
@@ -50,7 +50,7 @@ Let's now add some data to this bad boy.
50
50
  {
51
51
  "type": ":preset",
52
52
  "params": {
53
- "data": ["nx1","nx2","nx3","nx4","nx5"]
53
+ "values": ["nx1","nx2","nx3","nx4","nx5"]
54
54
  }
55
55
  }
56
56
  ```
@@ -59,13 +59,13 @@ Let's now add some data to this bad boy.
59
59
  => [["nx1", "nx2", "nx3", "nx4", "nx5"]]
60
60
  ```
61
61
 
62
- Now we could add the other rows ourselves, by adding more rows to "data":
62
+ Now we could add the other rows ourselves, by adding more rows to "values":
63
63
 
64
64
  ```
65
65
  {
66
66
  "type": ":preset",
67
67
  "params": {
68
- "data": [
68
+ "values": [
69
69
  ["nx1","nx2","nx3","nx4","nx5"],
70
70
  [1, 2, 3, 4, 5],
71
71
  [2, 4, 6, 8, 10],
@@ -98,7 +98,7 @@ This allows us to string reports together in the same template.
98
98
  {
99
99
  "type": ":preset",
100
100
  "params": {
101
- "data": ["nx1","nx2","nx3","nx4","nx5"]
101
+ "values": ["nx1","nx2","nx3","nx4","nx5"]
102
102
  }
103
103
  }
104
104
  ]
@@ -119,7 +119,7 @@ Set both to be an empty array.
119
119
  {
120
120
  "type": ":preset",
121
121
  "params": {
122
- "data": ["nx1","nx2","nx3","nx4","nx5"]
122
+ "values": ["nx1","nx2","nx3","nx4","nx5"]
123
123
  }
124
124
  },
125
125
  {
@@ -174,7 +174,7 @@ Using this, we can write a much smarter report.
174
174
  {
175
175
  "type": ":preset",
176
176
  "params": {
177
- "data": ["nx1","nx2","nx3","nx4","nx5"]
177
+ "values": ["nx1","nx2","nx3","nx4","nx5"]
178
178
  }
179
179
  },
180
180
  {
@@ -242,7 +242,7 @@ Let's add this now as the target of our report:
242
242
  {
243
243
  "type": ":preset",
244
244
  "params": {
245
- "data": ["nx1","nx2","nx3","nx4","nx5"]
245
+ "values": ["nx1","nx2","nx3","nx4","nx5"]
246
246
  }
247
247
  },
248
248
  {
@@ -2,9 +2,10 @@ module Reportinator
2
2
  class Base
3
3
  include ActiveModel::API
4
4
  include ActiveModel::Attributes
5
-
6
5
  require_rel "."
7
6
 
7
+ include Helpers
8
+
8
9
  def self.config
9
10
  Reportinator.config
10
11
  end
@@ -9,6 +9,10 @@ module Reportinator
9
9
  DEFAULT_FUNCTIONS = [
10
10
  "Reportinator::HelperArrayFunction",
11
11
  "Reportinator::JoinArrayFunction",
12
+ "Reportinator::RangeArrayFunction",
13
+ "Reportinator::StringArrayFunction",
14
+ "Reportinator::SnippetArrayFunction",
15
+ "Reportinator::FlattenArrayFunction",
12
16
  "Reportinator::MethodArrayFunction",
13
17
  "Reportinator::AdditionStringFunction",
14
18
  "Reportinator::ConstantStringFunction",
@@ -20,11 +24,13 @@ module Reportinator
20
24
  "Reportinator::SymbolStringFunction",
21
25
  "Reportinator::VariableStringFunction"
22
26
  ]
27
+ DEFAULT_UNPARSEDS = [:snippets]
23
28
 
24
29
  attribute :report_directories, default: []
25
30
  attribute :report_suffixes, default: []
26
31
  attribute :report_types, default: {}
27
32
  attribute :parser_functions, default: []
33
+ attribute :unparsed_metadata, default: []
28
34
  attribute :output_directory, default: "reports"
29
35
 
30
36
  def configured_directories
@@ -44,5 +50,9 @@ module Reportinator
44
50
  functions = DEFAULT_FUNCTIONS + parser_functions
45
51
  functions.map { |function| function.constantize }
46
52
  end
53
+
54
+ def configured_metadata
55
+ DEFAULT_UNPARSEDS + unparsed_metadata
56
+ end
47
57
  end
48
58
  end
@@ -1,18 +1,18 @@
1
1
  module Reportinator
2
2
  class Function < Base
3
3
  attribute :element
4
- attribute :variables, default: {}
4
+ attribute :metadata, default: {}
5
5
 
6
- def self.parse(element, variables = {})
7
- new(element: element, variables: variables).get
6
+ def self.parse(element, metadata = {})
7
+ new(element: element, metadata: metadata).get
8
8
  end
9
9
 
10
10
  def parse_value(value)
11
- ValueParser.parse(value, variables)
11
+ ValueParser.parse(value, metadata)
12
12
  end
13
13
 
14
14
  def parse_and_execute_value(target, value)
15
- ValueParser.parse_and_execute(target, value, variables)
15
+ ValueParser.parse_and_execute(target, value, metadata)
16
16
  end
17
17
 
18
18
  def prefixes
@@ -0,0 +1,12 @@
1
+ module Reportinator
2
+ class FlattenArrayFunction < ArrayFunction
3
+ PREFIXES = [">flatten"]
4
+
5
+ def output
6
+ array = []
7
+ array.append parse_value(target)
8
+ array.append parse_value(values)
9
+ array.flatten
10
+ end
11
+ end
12
+ end
@@ -1,6 +1,6 @@
1
1
  module Reportinator
2
2
  class HelperArrayFunction < ArrayFunction
3
- PREFIXES = [">strf", ">offset", ">title"]
3
+ PREFIXES = [">strf", ">offset", ">title", ">sum"]
4
4
 
5
5
  INTERVALS = {
6
6
  days: {start: "at_beginning_of_day", end: "at_end_of_day"},
@@ -15,6 +15,7 @@ module Reportinator
15
15
  return parse_strftime if prefix == ">strf"
16
16
  return parse_offset if prefix == ">offset"
17
17
  return parse_title if prefix == ">title"
18
+ return parse_sum if prefix == ">sum"
18
19
  element
19
20
  end
20
21
 
@@ -55,6 +56,11 @@ module Reportinator
55
56
  to_join.join(" ").titleize
56
57
  end
57
58
 
59
+ def parse_sum
60
+ sum_values = parsed_values.append parsed_target
61
+ sum_values.sum { |value| parse_value("!n #{value}") }
62
+ end
63
+
58
64
  def parsed_target
59
65
  @parsed_target ||= parse_target
60
66
  end
@@ -3,7 +3,7 @@ module Reportinator
3
3
  PREFIXES = [">join"]
4
4
 
5
5
  def output
6
- joiner = ValueParser.parse(target, variables)
6
+ joiner = parse_value(target)
7
7
  joiner = (joiner.instance_of?(String) ? joiner : target)
8
8
  values.map { |value| parse_value(value) }.join(joiner)
9
9
  end
@@ -0,0 +1,11 @@
1
+ module Reportinator
2
+ class RangeArrayFunction < ArrayFunction
3
+ PREFIXES = [">range"]
4
+
5
+ def output
6
+ start_value = parse_value(target)
7
+ end_value = parse_value(values[0])
8
+ (start_value..end_value)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,30 @@
1
+ module Reportinator
2
+ class SnippetArrayFunction < ArrayFunction
3
+ PREFIXES = [">snippet"]
4
+
5
+ def output
6
+ name = target
7
+ name.strip! if name.instance_of? String
8
+ parsed_name = parse_value(name)
9
+ snippet = find_snippet(parsed_name)
10
+ return "Missing Snippet" unless snippet.present?
11
+ parse_snippet(snippet)
12
+ end
13
+
14
+ def find_snippet(name)
15
+ snippets = metadata[:snippets]
16
+ return false unless snippets.present?
17
+ return false unless snippets[name].present?
18
+ snippets[name]
19
+ end
20
+
21
+ def parse_snippet(snippet)
22
+ snippet_metadata = metadata.dup
23
+ snippet_metadata.delete :snippets
24
+ variables = values[0]
25
+ parsed_variables = parse_value(variables)
26
+ input_metadata = merge_hash(snippet_metadata, {variables: parsed_variables})
27
+ ValueParser.parse(snippet, input_metadata)
28
+ end
29
+ end
30
+ end