metanorma-plugin-lutaml 0.7.17 → 0.7.19
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d95bbbcc424c384a0c2d58374f647eda5e6efc60278c7a2e69b6eefec2e8b012
|
4
|
+
data.tar.gz: 00b430d79891b1f9143186a3af2a5eddabe01c8f89f77431b494908164c67bcb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f07e00a438eb808adda1c72985a15e5fca581e2afeff305acc78164cf698ec6942c57da3863b767f2551ede925fc8b1eb804977665ff15d07204bb4bf637a60
|
7
|
+
data.tar.gz: 9840d71a72679997ec0d6f9c11139c063a843cb1fa3f1920e7a770505d3357b026cde3e67270d8b216fefbeb0f6bfbd595b57e85007896490164f377ed27f2b3
|
data/README.adoc
CHANGED
@@ -145,7 +145,7 @@ And the `lutaml_express` block:
|
|
145
145
|
|
146
146
|
[source,adoc]
|
147
147
|
-----
|
148
|
-
[
|
148
|
+
[lutaml_express_liquid,example.exp,my_context]
|
149
149
|
----
|
150
150
|
{% for schema in my_context.schemas %}
|
151
151
|
== {{schema.id}}
|
@@ -169,9 +169,9 @@ Where:
|
|
169
169
|
|
170
170
|
* `{example.exp}` is the location of the EXPRESS schema file (`*.exp`) that
|
171
171
|
contains data to be loaded. Location of the file is computed relative to the
|
172
|
-
source directory that `[
|
173
|
-
`[
|
174
|
-
`/foo/bar/doc.adoc`, the data file is expected to be found at
|
172
|
+
source directory that `[lutaml_express_liquid]` is used (e.g., if
|
173
|
+
`[lutaml_express_liquid,example.exp,my_context]` is invoked in an `.adoc` file
|
174
|
+
located at `/foo/bar/doc.adoc`, the data file is expected to be found at
|
175
175
|
`/foo/bar/example.exp`);
|
176
176
|
|
177
177
|
* `{my_context}` is the name where the EXPRESS Repository read from the `.exp`
|
@@ -225,7 +225,7 @@ Example of usage:
|
|
225
225
|
Author
|
226
226
|
:lutaml-express-index: index_name; /path/to/express_files; cache=/path/to/cache_file.yaml
|
227
227
|
|
228
|
-
[
|
228
|
+
[lutaml_express_liquid,index_name,context]
|
229
229
|
----
|
230
230
|
{% for schema in context.schemas %}
|
231
231
|
== {{schema.id}}
|
@@ -233,9 +233,16 @@ Author
|
|
233
233
|
----
|
234
234
|
-----
|
235
235
|
|
236
|
-
|
236
|
+
* The `lutaml_express_liquid` macro processes the EXPRESS files specified by
|
237
|
+
the `index_name` and makes them available in the `context` as
|
238
|
+
Liquid Drops object.
|
237
239
|
|
238
|
-
|
240
|
+
* The Liquid template inside the macro block iterates over the `schemas` in
|
241
|
+
the `context` and renders the attributes of each schema such as `id`.
|
242
|
+
|
243
|
+
=== Using `config_yaml`
|
244
|
+
|
245
|
+
This functionality allows `[lutaml_express_liquid]` blocks to load a full set of
|
239
246
|
EXPRESS schemas in one index, and then provide a select ("filter") option
|
240
247
|
per-block via a separate YAML file.
|
241
248
|
|
@@ -243,8 +250,8 @@ per-block via a separate YAML file.
|
|
243
250
|
-----
|
244
251
|
:lutaml-express-index: all_schemas; ../schemas_all.yaml;
|
245
252
|
|
246
|
-
[
|
247
|
-
|
253
|
+
[lutaml_express_liquid,all_schemas,context,config_yaml=schemas.yaml]
|
254
|
+
---
|
248
255
|
{% assign selected = context.schemas | where: "selected" %}
|
249
256
|
{% render "templates/resources/schema" for selected as schema %}
|
250
257
|
----
|
@@ -282,9 +289,9 @@ The resulting block adds the `select` attribute to every schema of the the
|
|
282
289
|
via Liquid:
|
283
290
|
|
284
291
|
[source,liquid]
|
285
|
-
-----
|
286
|
-
[lutaml_express,schemas_1,repo,leveloffset=+1,config_yaml=select.yaml]
|
287
292
|
----
|
293
|
+
[lutaml_express_liquid,schemas_1,repo,config_yaml=select.yaml]
|
294
|
+
---
|
288
295
|
{% assign selected = repo.schemas | where: "selected" %}
|
289
296
|
... do things with `selected` ...
|
290
297
|
---
|
@@ -5,7 +5,6 @@ require "asciidoctor"
|
|
5
5
|
require "asciidoctor/reader"
|
6
6
|
require "lutaml"
|
7
7
|
require "metanorma/plugin/lutaml/utils"
|
8
|
-
require "metanorma/plugin/lutaml/express_remarks_decorator"
|
9
8
|
require "metanorma/plugin/lutaml/asciidoctor/preprocessor"
|
10
9
|
|
11
10
|
module Metanorma
|
@@ -15,12 +14,12 @@ module Metanorma
|
|
15
14
|
class LutamlPreprocessor < ::Asciidoctor::Extensions::Preprocessor
|
16
15
|
REMARKS_ATTRIBUTE = "remarks"
|
17
16
|
|
18
|
-
def process(document, reader)
|
17
|
+
def process(document, reader) # rubocop:disable Metrics/MethodLength
|
19
18
|
r = Asciidoctor::PreprocessorNoIfdefsReader.new(document,
|
20
19
|
reader.lines)
|
21
20
|
input_lines = r.readlines.to_enum
|
22
21
|
|
23
|
-
|
22
|
+
has_lutaml_liquid = input_lines.any? { |line| lutaml_liquid?(line) }
|
24
23
|
|
25
24
|
express_indexes = Utils.parse_document_express_indexes(
|
26
25
|
document,
|
@@ -33,7 +32,7 @@ module Metanorma
|
|
33
32
|
express_indexes: express_indexes,
|
34
33
|
)
|
35
34
|
|
36
|
-
log(document, result_content) if
|
35
|
+
log(document, result_content) if has_lutaml_liquid
|
37
36
|
|
38
37
|
Asciidoctor::PreprocessorNoIfdefsReader.new(document, result_content)
|
39
38
|
end
|
@@ -46,8 +45,8 @@ module Metanorma
|
|
46
45
|
end
|
47
46
|
end
|
48
47
|
|
49
|
-
def
|
50
|
-
line.match(/^\[(?:\blutaml\b|\blutaml_express\b),(?<index_names>[^,]+)?,?(?<context_name>[^,]+)?(?<options>,.*)?\]/)
|
48
|
+
def lutaml_liquid?(line)
|
49
|
+
line.match(/^\[(?:\blutaml\b|\blutaml_express\b|\blutaml_express_liquid\b),(?<index_names>[^,]+)?,?(?<context_name>[^,]+)?(?<options>,.*)?\]/) # rubocop:disable Layout/LineLength
|
51
50
|
end
|
52
51
|
|
53
52
|
def load_lutaml_file(document, file_path)
|
@@ -61,28 +60,19 @@ module Metanorma
|
|
61
60
|
|
62
61
|
private
|
63
62
|
|
64
|
-
def process_input_lines(
|
65
|
-
document:,
|
66
|
-
input_lines:,
|
67
|
-
express_indexes:
|
68
|
-
)
|
69
|
-
|
63
|
+
def process_input_lines(document:, input_lines:, express_indexes:)
|
70
64
|
result = []
|
71
65
|
loop do
|
72
66
|
result.push(
|
73
|
-
*process_text_blocks(
|
74
|
-
document,
|
75
|
-
input_lines,
|
76
|
-
express_indexes,
|
77
|
-
),
|
67
|
+
*process_text_blocks(document, input_lines, express_indexes),
|
78
68
|
)
|
79
69
|
end
|
80
70
|
result
|
81
71
|
end
|
82
72
|
|
83
|
-
def process_text_blocks(document, input_lines, express_indexes)
|
73
|
+
def process_text_blocks(document, input_lines, express_indexes) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
|
84
74
|
line = input_lines.next
|
85
|
-
block_header_match =
|
75
|
+
block_header_match = lutaml_liquid?(line)
|
86
76
|
|
87
77
|
return [line] if block_header_match.nil?
|
88
78
|
|
@@ -94,7 +84,7 @@ module Metanorma
|
|
94
84
|
|
95
85
|
end_mark = input_lines.next
|
96
86
|
|
97
|
-
|
87
|
+
render_liquid_template(
|
98
88
|
document: document,
|
99
89
|
lines: extract_block_lines(input_lines, end_mark),
|
100
90
|
index_names: index_names,
|
@@ -112,19 +102,16 @@ module Metanorma
|
|
112
102
|
block
|
113
103
|
end
|
114
104
|
|
115
|
-
def
|
105
|
+
def gather_context_liquid_items( # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/ParameterLists
|
106
|
+
index_names:, document:, indexes:, options: {}
|
107
|
+
)
|
116
108
|
index_names.map do |path|
|
117
|
-
# TODO: Rephrase of the below TODO message.
|
118
|
-
# ::Lutaml::Parser.parse(file_list) can return an Array or just one.
|
119
|
-
# TODO: decide how to handle expressir multiply file parse as one
|
120
|
-
# object and lutaml
|
121
|
-
|
122
|
-
# Does this condition ever happen? That is only if the
|
123
|
-
# `lutaml-express-index` condition is not set
|
124
109
|
if indexes[path]
|
125
|
-
indexes[path][:
|
110
|
+
indexes[path][:liquid_drop] ||=
|
111
|
+
indexes[path][:wrapper].original_document.to_liquid(
|
112
|
+
options: options,
|
113
|
+
)
|
126
114
|
else
|
127
|
-
|
128
115
|
full_path = Utils.relative_file_path(document, path)
|
129
116
|
unless File.file?(full_path)
|
130
117
|
raise StandardError.new(
|
@@ -135,8 +122,9 @@ module Metanorma
|
|
135
122
|
end
|
136
123
|
wrapper = load_lutaml_file(document, path)
|
137
124
|
indexes[path] = {
|
138
|
-
|
139
|
-
|
125
|
+
liquid_drop: wrapper.original_document.to_liquid(
|
126
|
+
options: options,
|
127
|
+
),
|
140
128
|
}
|
141
129
|
end
|
142
130
|
|
@@ -144,7 +132,7 @@ module Metanorma
|
|
144
132
|
end
|
145
133
|
end
|
146
134
|
|
147
|
-
def read_config_yaml_file(document, file_path)
|
135
|
+
def read_config_yaml_file(document, file_path) # rubocop:disable Metrics/MethodLength
|
148
136
|
return {} if file_path.nil?
|
149
137
|
|
150
138
|
relative_file_path = Utils.relative_file_path(document, file_path)
|
@@ -156,8 +144,8 @@ module Metanorma
|
|
156
144
|
if config_yaml["schemas"]
|
157
145
|
unless config_yaml["schemas"].is_a?(Hash)
|
158
146
|
raise StandardError.new(
|
159
|
-
"[
|
160
|
-
"file that has the `schema` key containing a hash.",
|
147
|
+
"[lutaml_express_liquid] attribute `config_yaml` must point " \
|
148
|
+
"to a YAML file that has the `schema` key containing a hash.",
|
161
149
|
)
|
162
150
|
end
|
163
151
|
|
@@ -167,35 +155,6 @@ module Metanorma
|
|
167
155
|
options
|
168
156
|
end
|
169
157
|
|
170
|
-
def decorate_schema_object(schema:, document:, indexes:, index_names:, # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/ParameterLists
|
171
|
-
selected:, options:)
|
172
|
-
# Mark a schema as "selected" with `.selected`
|
173
|
-
schema["selected"] = true if selected
|
174
|
-
|
175
|
-
# Provide pretty-formatted code under `.formatted`
|
176
|
-
_index_found_key, index_found_value = indexes.detect do |k, v|
|
177
|
-
_found = get_original_document(v[:wrapper]).schemas.detect do |s|
|
178
|
-
s.id == schema["id"]
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
schema["formatted"] = get_original_document(
|
183
|
-
index_found_value[:wrapper],
|
184
|
-
).schemas.detect do |s|
|
185
|
-
s.id == schema["id"]
|
186
|
-
end.to_s(no_remarks: true)
|
187
|
-
|
188
|
-
# Decorate the remaining things
|
189
|
-
decorate_context_items(
|
190
|
-
schema,
|
191
|
-
options.merge(
|
192
|
-
"relative_path_prefix" =>
|
193
|
-
Utils.relative_file_path(document,
|
194
|
-
File.dirname(schema["file"])),
|
195
|
-
),
|
196
|
-
) || {}
|
197
|
-
end
|
198
|
-
|
199
158
|
def get_original_document(wrapper)
|
200
159
|
doc = wrapper
|
201
160
|
return doc if doc.instance_of?(::Lutaml::XMI::RootDrop)
|
@@ -203,38 +162,26 @@ selected:, options:)
|
|
203
162
|
doc.original_document
|
204
163
|
end
|
205
164
|
|
206
|
-
def
|
207
|
-
options:, indexes:)
|
165
|
+
def render_liquid_template(document:, lines:, context_name:, # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/ParameterLists
|
166
|
+
index_names:, options:, indexes:)
|
208
167
|
config_yaml_path = options.delete("config_yaml")
|
209
168
|
config = read_config_yaml_file(document, config_yaml_path)
|
210
|
-
|
169
|
+
if config["selected_schemas"]
|
170
|
+
options["selected_schemas"] = config["selected_schemas"]
|
171
|
+
end
|
211
172
|
|
212
|
-
|
173
|
+
all_items = gather_context_liquid_items(
|
213
174
|
index_names: index_names,
|
214
175
|
document: document,
|
215
176
|
indexes: indexes,
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
serialized_hash["schemas"]&.map! do |schema|
|
220
|
-
decorate_schema_object(
|
221
|
-
schema: schema,
|
222
|
-
document: document,
|
223
|
-
index_names: index_names,
|
224
|
-
indexes: indexes,
|
225
|
-
selected: selected_schemas && selected_schemas.include?(
|
226
|
-
schema["id"],
|
227
|
-
),
|
228
|
-
options: options,
|
229
|
-
)
|
230
|
-
end
|
177
|
+
options: options.merge("document" => document),
|
178
|
+
)
|
231
179
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
)
|
180
|
+
all_items.map do |item|
|
181
|
+
repo_drop = item[:liquid_drop]
|
182
|
+
template = ::Liquid::Template.parse(lines.join("\n"))
|
183
|
+
template.assigns[context_name] = repo_drop
|
184
|
+
template.render
|
238
185
|
end.flatten
|
239
186
|
rescue StandardError => e
|
240
187
|
::Metanorma::Util.log(
|
@@ -252,48 +199,6 @@ options:, indexes:)
|
|
252
199
|
.map { |elem| elem.map(&:strip) }
|
253
200
|
.to_h
|
254
201
|
end
|
255
|
-
|
256
|
-
def decorate_context_item(key, val, options)
|
257
|
-
if key == REMARKS_ATTRIBUTE
|
258
|
-
return [
|
259
|
-
key,
|
260
|
-
val&.map do |remark|
|
261
|
-
Metanorma::Plugin::Lutaml::ExpressRemarksDecorator
|
262
|
-
.call(remark, options)
|
263
|
-
end,
|
264
|
-
]
|
265
|
-
end
|
266
|
-
|
267
|
-
case val
|
268
|
-
when Hash
|
269
|
-
[key, decorate_context_items(val, options)]
|
270
|
-
when Array
|
271
|
-
[key, val.map { |n| decorate_context_items(n, options) }]
|
272
|
-
else
|
273
|
-
[key, val]
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
def decorate_context_items(item, options)
|
278
|
-
return item unless item.is_a?(Hash)
|
279
|
-
|
280
|
-
item.map do |(key, val)|
|
281
|
-
decorate_context_item(key, val, options)
|
282
|
-
end.to_h
|
283
|
-
end
|
284
|
-
|
285
|
-
def render_block(block_lines:, context_items:, context_name:, document:)
|
286
|
-
render_result, errors = Utils.render_liquid_string(
|
287
|
-
template_string: block_lines.join("\n"),
|
288
|
-
context_items: context_items,
|
289
|
-
context_name: context_name,
|
290
|
-
document: document,
|
291
|
-
)
|
292
|
-
|
293
|
-
Utils.notify_render_errors(document, errors)
|
294
|
-
|
295
|
-
render_result.split("\n")
|
296
|
-
end
|
297
202
|
end
|
298
203
|
end
|
299
204
|
end
|
@@ -27,9 +27,9 @@ Gem::Specification.new do |spec|
|
|
27
27
|
|
28
28
|
spec.add_dependency "asciidoctor"
|
29
29
|
spec.add_dependency "coradoc", "~> 1.1.1"
|
30
|
-
spec.add_dependency "expressir", "~> 2.1.
|
30
|
+
spec.add_dependency "expressir", "~> 2.1.11"
|
31
31
|
spec.add_dependency "liquid"
|
32
|
-
spec.add_dependency "lutaml", "
|
32
|
+
spec.add_dependency "lutaml", "~> 0.9.25"
|
33
33
|
spec.add_dependency "ogc-gml", "1.0.0"
|
34
34
|
spec.add_dependency "relaton-cli"
|
35
35
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metanorma-plugin-lutaml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 2.1.
|
47
|
+
version: 2.1.11
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 2.1.
|
54
|
+
version: 2.1.11
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: liquid
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,16 +70,16 @@ dependencies:
|
|
70
70
|
name: lutaml
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.9.
|
75
|
+
version: 0.9.25
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.9.
|
82
|
+
version: 0.9.25
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: ogc-gml
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -313,7 +313,6 @@ files:
|
|
313
313
|
- bin/setup
|
314
314
|
- lib/metanorma-plugin-lutaml.rb
|
315
315
|
- lib/metanorma/plugin/lutaml/asciidoctor/preprocessor.rb
|
316
|
-
- lib/metanorma/plugin/lutaml/express_remarks_decorator.rb
|
317
316
|
- lib/metanorma/plugin/lutaml/liquid/custom_filters.rb
|
318
317
|
- lib/metanorma/plugin/lutaml/liquid/multiply_local_file_system.rb
|
319
318
|
- lib/metanorma/plugin/lutaml/liquid_drops/gml_dictionary_drop.rb
|
@@ -1,78 +0,0 @@
|
|
1
|
-
module Metanorma
|
2
|
-
module Plugin
|
3
|
-
module Lutaml
|
4
|
-
class ExpressRemarksDecorator
|
5
|
-
RELATIVE_PREFIX_MACRO_REGEXP = /^(link|image|video|audio|include)(:+)?(?![^\/:]+:\/\/|[A-Z]:\/|\/)([^:\[]+)(\[.*\])?$/.freeze
|
6
|
-
|
7
|
-
attr_reader :remark, :options
|
8
|
-
|
9
|
-
def self.call(remark, options)
|
10
|
-
new(remark, options).call
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize(remark, options)
|
14
|
-
@remark = remark
|
15
|
-
@options = options
|
16
|
-
end
|
17
|
-
|
18
|
-
def call
|
19
|
-
result = remark
|
20
|
-
if options["leveloffset"]
|
21
|
-
result = process_remark_offsets(result, options["leveloffset"].to_i)
|
22
|
-
end
|
23
|
-
if options["relative_path_prefix"]
|
24
|
-
result = update_relative_paths(result,
|
25
|
-
options["relative_path_prefix"])
|
26
|
-
end
|
27
|
-
result
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def update_relative_paths(string, path_prefix)
|
33
|
-
string
|
34
|
-
.split("\n")
|
35
|
-
.map do |line|
|
36
|
-
if line.match?(RELATIVE_PREFIX_MACRO_REGEXP)
|
37
|
-
prefix_relative_paths(line, path_prefix)
|
38
|
-
else
|
39
|
-
line
|
40
|
-
end
|
41
|
-
end
|
42
|
-
.join("\n")
|
43
|
-
end
|
44
|
-
|
45
|
-
def prefix_relative_paths(line, path_prefix)
|
46
|
-
line.gsub(RELATIVE_PREFIX_MACRO_REGEXP) do |_match|
|
47
|
-
prefixed_path = File.join(path_prefix, $3.strip)
|
48
|
-
# When we are dealing with a relative path of a template:
|
49
|
-
# ../path/to/file we need to transform it into
|
50
|
-
# the absolute one because `image::` macro wont understand it other way
|
51
|
-
prefixed_path = File.absolute_path(prefixed_path) if prefixed_path.start_with?("../")
|
52
|
-
full_path = File.expand_path(prefixed_path)
|
53
|
-
"#{$1}#{$2}#{full_path}#{$4}"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def process_remark_offsets(string, offset)
|
58
|
-
string
|
59
|
-
.split("\n")
|
60
|
-
.map do |line|
|
61
|
-
if line.match?(/^=/)
|
62
|
-
set_string_offsets(line, offset)
|
63
|
-
else
|
64
|
-
line
|
65
|
-
end
|
66
|
-
end
|
67
|
-
.join("\n")
|
68
|
-
end
|
69
|
-
|
70
|
-
def set_string_offsets(string, offset)
|
71
|
-
return "#{'=' * offset}#{string}" if offset.positive?
|
72
|
-
|
73
|
-
string.gsub(/^={#{offset * -1}}/, "")
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|