fmt 0.1.3 → 0.3.1
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 +4 -4
- data/README.md +179 -86
- data/lib/fmt/boot.rb +50 -0
- data/lib/fmt/lru_cache.rb +181 -0
- data/lib/fmt/mixins/matchable.rb +26 -0
- data/lib/fmt/models/arguments.rb +194 -0
- data/lib/fmt/models/embed.rb +48 -0
- data/lib/fmt/models/macro.rb +58 -0
- data/lib/fmt/models/model.rb +66 -0
- data/lib/fmt/models/pipeline.rb +47 -0
- data/lib/fmt/models/template.rb +55 -0
- data/lib/fmt/node.rb +128 -0
- data/lib/fmt/parsers/arguments_parser.rb +43 -0
- data/lib/fmt/parsers/embed_parser.rb +54 -0
- data/lib/fmt/parsers/macro_parser.rb +113 -0
- data/lib/fmt/parsers/parser.rb +56 -0
- data/lib/fmt/parsers/pipeline_parser.rb +41 -0
- data/lib/fmt/parsers/template_parser.rb +125 -0
- data/lib/fmt/refinements/kernel_refinement.rb +33 -0
- data/lib/fmt/registries/native_registry.rb +66 -0
- data/lib/fmt/registries/rainbow_registry.rb +36 -0
- data/lib/fmt/registries/registry.rb +127 -0
- data/lib/fmt/renderer.rb +132 -0
- data/lib/fmt/sigils.rb +23 -0
- data/lib/fmt/token.rb +126 -0
- data/lib/fmt/tokenizer.rb +96 -0
- data/lib/fmt/version.rb +3 -1
- data/lib/fmt.rb +50 -12
- data/sig/generated/fmt/boot.rbs +2 -0
- data/sig/generated/fmt/lru_cache.rbs +122 -0
- data/sig/generated/fmt/mixins/matchable.rbs +18 -0
- data/sig/generated/fmt/models/arguments.rbs +115 -0
- data/sig/generated/fmt/models/embed.rbs +34 -0
- data/sig/generated/fmt/models/macro.rbs +37 -0
- data/sig/generated/fmt/models/model.rbs +45 -0
- data/sig/generated/fmt/models/pipeline.rbs +31 -0
- data/sig/generated/fmt/models/template.rbs +33 -0
- data/sig/generated/fmt/node.rbs +64 -0
- data/sig/generated/fmt/parsers/arguments_parser.rbs +25 -0
- data/sig/generated/fmt/parsers/embed_parser.rbs +36 -0
- data/sig/generated/fmt/parsers/macro_parser.rbs +60 -0
- data/sig/generated/fmt/parsers/parser.rbs +44 -0
- data/sig/generated/fmt/parsers/pipeline_parser.rbs +25 -0
- data/sig/generated/fmt/parsers/template_parser.rbs +50 -0
- data/sig/generated/fmt/refinements/kernel_refinement.rbs +23 -0
- data/sig/generated/fmt/registries/native_registry.rbs +19 -0
- data/sig/generated/fmt/registries/rainbow_registry.rbs +11 -0
- data/sig/generated/fmt/registries/registry.rbs +69 -0
- data/sig/generated/fmt/renderer.rbs +70 -0
- data/sig/generated/fmt/sigils.rbs +30 -0
- data/sig/generated/fmt/token.rbs +77 -0
- data/sig/generated/fmt/tokenizer.rbs +51 -0
- data/sig/generated/fmt/version.rbs +5 -0
- data/sig/generated/fmt.rbs +41 -0
- metadata +126 -18
- data/lib/fmt/embed.rb +0 -19
- data/lib/fmt/filter.rb +0 -32
- data/lib/fmt/filter_groups/filter_group.rb +0 -56
- data/lib/fmt/filter_groups/rainbow_filter_group.rb +0 -27
- data/lib/fmt/filter_groups/string_filter_group.rb +0 -28
- data/lib/fmt/formatter.rb +0 -60
- data/lib/fmt/scanners/base_scanner.rb +0 -41
- data/lib/fmt/scanners/embed_scanner.rb +0 -56
- data/lib/fmt/scanners/filter_scanner.rb +0 -31
- data/lib/fmt/scanners/key_scanner.rb +0 -15
- data/lib/fmt/scanners.rb +0 -3
- data/lib/fmt/transformer.rb +0 -57
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "filter_group"
|
4
|
-
|
5
|
-
module Fmt
|
6
|
-
class StringFilterGroup < FilterGroup
|
7
|
-
def initialize
|
8
|
-
super
|
9
|
-
|
10
|
-
# rubocop:disable Layout/ExtraSpacing AllowForAlignment
|
11
|
-
add :capitalize, ->(s) { s.capitalize }
|
12
|
-
add :chomp, ->(s) { s.chomp }
|
13
|
-
add :chop, ->(s) { s.chop }
|
14
|
-
add :downcase, ->(s) { s.downcase }
|
15
|
-
add :lstrip, ->(s) { s.lstrip }
|
16
|
-
add :reverse, ->(s) { s.reverse }
|
17
|
-
add :rstrip, ->(s) { s.rstrip }
|
18
|
-
add :shellescape, ->(s) { s.shellescape }
|
19
|
-
add :strip, ->(s) { s.strip }
|
20
|
-
add :succ, ->(s) { s.succ }
|
21
|
-
add :swapcase, ->(s) { s.swapcase }
|
22
|
-
add :undump, ->(s) { s.undump }
|
23
|
-
add :unicode_normalize, ->(s) { s.unicode_normalize }
|
24
|
-
add :upcase, ->(s) { s.upcase }
|
25
|
-
# rubocop:enable Layout/ExtraSpacing AllowForAlignment
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/lib/fmt/formatter.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "singleton"
|
4
|
-
require_relative "filter_groups/filter_group"
|
5
|
-
require_relative "filter_groups/rainbow_filter_group"
|
6
|
-
require_relative "filter_groups/string_filter_group"
|
7
|
-
require_relative "scanners"
|
8
|
-
require_relative "transformer"
|
9
|
-
|
10
|
-
module Fmt
|
11
|
-
class Formatter
|
12
|
-
include Singleton
|
13
|
-
|
14
|
-
attr_reader :filters
|
15
|
-
|
16
|
-
def add_rainbow_filters
|
17
|
-
filters.merge! Fmt::RainbowFilterGroup.new.to_h
|
18
|
-
end
|
19
|
-
|
20
|
-
def add_filter(...)
|
21
|
-
filters.add(...)
|
22
|
-
end
|
23
|
-
|
24
|
-
def format(string, **locals)
|
25
|
-
result = string.to_s
|
26
|
-
transformer = next_transformer(result)
|
27
|
-
|
28
|
-
while transformer
|
29
|
-
result = transformer.transform(result, **locals)
|
30
|
-
transformer = next_transformer(result)
|
31
|
-
end
|
32
|
-
|
33
|
-
result
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def initialize
|
39
|
-
super
|
40
|
-
@filters = Fmt::FilterGroup.new.merge!(Fmt::StringFilterGroup.new)
|
41
|
-
end
|
42
|
-
|
43
|
-
def next_transformer(string)
|
44
|
-
embed_scanner = Fmt::EmbedScanner.new(string)
|
45
|
-
embed_scanner.scan
|
46
|
-
|
47
|
-
key_scanner = Fmt::KeyScanner.new(string)
|
48
|
-
key = key_scanner.scan
|
49
|
-
return nil unless key
|
50
|
-
|
51
|
-
filter_scanner = Fmt::FilterScanner.new(key_scanner.rest, registered_filters: filters)
|
52
|
-
filter_string = filter_scanner.scan
|
53
|
-
|
54
|
-
Fmt::Transformer.new key.to_sym,
|
55
|
-
embeds: embed_scanner.embeds,
|
56
|
-
filters: filter_scanner.filters,
|
57
|
-
placeholder: "%{#{key}}#{filter_string}".strip
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "forwardable"
|
4
|
-
require "strscan"
|
5
|
-
|
6
|
-
module Fmt
|
7
|
-
class BaseScanner
|
8
|
-
extend Forwardable
|
9
|
-
|
10
|
-
def initialize(string)
|
11
|
-
@string_scanner = StringScanner.new(string)
|
12
|
-
end
|
13
|
-
|
14
|
-
def_delegators :string_scanner, :string, :rest
|
15
|
-
attr_reader :value
|
16
|
-
|
17
|
-
def performed?
|
18
|
-
!!@performed
|
19
|
-
end
|
20
|
-
|
21
|
-
def reset
|
22
|
-
@performed = false
|
23
|
-
string_scanner.reset
|
24
|
-
end
|
25
|
-
|
26
|
-
def scan
|
27
|
-
return if performed?
|
28
|
-
@performed = true
|
29
|
-
perform
|
30
|
-
value
|
31
|
-
end
|
32
|
-
|
33
|
-
protected
|
34
|
-
|
35
|
-
attr_reader :string_scanner
|
36
|
-
|
37
|
-
def perform
|
38
|
-
raise NotImplementedError
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "base_scanner"
|
4
|
-
require_relative "../embed"
|
5
|
-
|
6
|
-
module Fmt
|
7
|
-
class EmbedScanner < BaseScanner
|
8
|
-
def initialize(string, root: nil)
|
9
|
-
super(string)
|
10
|
-
@root ||= root || self
|
11
|
-
@embeds = []
|
12
|
-
end
|
13
|
-
|
14
|
-
def embeds
|
15
|
-
root? ? @embeds : root.embeds
|
16
|
-
end
|
17
|
-
|
18
|
-
attr_reader :root
|
19
|
-
|
20
|
-
def root?
|
21
|
-
root == self
|
22
|
-
end
|
23
|
-
|
24
|
-
protected
|
25
|
-
|
26
|
-
def includes_embed?(string)
|
27
|
-
string.match?(/[{]{2}/)
|
28
|
-
end
|
29
|
-
|
30
|
-
def next_scanner(string)
|
31
|
-
Fmt::EmbedScanner.new string, root: root
|
32
|
-
end
|
33
|
-
|
34
|
-
def scan_embeds(string)
|
35
|
-
return unless includes_embed?(string)
|
36
|
-
|
37
|
-
string = string[string.index(/[{]{2}/) + 2..]
|
38
|
-
scanner = next_scanner(string)
|
39
|
-
while (embed = scanner.scan)
|
40
|
-
embeds << Fmt::Embed.new(embed)
|
41
|
-
scanner = next_scanner(scanner.rest)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def perform?
|
46
|
-
!string.start_with?("}")
|
47
|
-
end
|
48
|
-
|
49
|
-
def perform
|
50
|
-
return unless perform?
|
51
|
-
scan_embeds string # <------------------------------------ extract embeds
|
52
|
-
string_scanner.scan_until(/[{]{2}/) # <------------------- advance to start
|
53
|
-
@value = string_scanner.scan_until(/[^}]*(?=[}]{2})/) # <- extract value
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "base_scanner"
|
4
|
-
|
5
|
-
module Fmt
|
6
|
-
class FilterScanner < BaseScanner
|
7
|
-
DELIMITER = "|"
|
8
|
-
|
9
|
-
def initialize(string, registered_filters:)
|
10
|
-
@registered_filters = registered_filters
|
11
|
-
@filters = []
|
12
|
-
super(string)
|
13
|
-
end
|
14
|
-
|
15
|
-
alias_method :filter_string, :value
|
16
|
-
attr_reader :filters
|
17
|
-
|
18
|
-
protected
|
19
|
-
|
20
|
-
attr_reader :registered_filters
|
21
|
-
|
22
|
-
def perform
|
23
|
-
@value = string_scanner.scan(/[^\s%]+/) # <- extract value
|
24
|
-
return unless string_scanner.matched?
|
25
|
-
|
26
|
-
@filters = value.split(DELIMITER)&.map do |name|
|
27
|
-
registered_filters.fetch name.to_sym, Fmt::Filter.new(name, name)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "base_scanner"
|
4
|
-
|
5
|
-
module Fmt
|
6
|
-
class KeyScanner < BaseScanner
|
7
|
-
protected
|
8
|
-
|
9
|
-
def perform
|
10
|
-
string_scanner.skip_until(/%[{]/) # <------------------------------ advance to start
|
11
|
-
@value = string_scanner.scan(/\w+/) if string_scanner.matched? # <- extract value
|
12
|
-
string_scanner.scan(/[}]/) if string_scanner.matched? # <---------- advance to end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/lib/fmt/scanners.rb
DELETED
data/lib/fmt/transformer.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Fmt
|
4
|
-
class Transformer
|
5
|
-
def initialize(key, embeds:, filters:, placeholder:)
|
6
|
-
@key = key
|
7
|
-
@embeds = embeds
|
8
|
-
@filters = filters
|
9
|
-
@placeholder = placeholder
|
10
|
-
end
|
11
|
-
|
12
|
-
attr_reader :key, :embeds, :filters, :placeholder, :proc_filters, :string_filters
|
13
|
-
|
14
|
-
def transform(string, **locals)
|
15
|
-
string = transform_embeds(string, **locals)
|
16
|
-
|
17
|
-
raise Fmt::Error, "Missing key! :#{key} <string=#{string.inspect} locals=#{locals.inspect}>" unless locals.key?(key)
|
18
|
-
|
19
|
-
replacement = locals[key]
|
20
|
-
|
21
|
-
filters.each do |filter|
|
22
|
-
if filter.string?
|
23
|
-
begin
|
24
|
-
replacement = sprintf("%#{filter.value}", replacement)
|
25
|
-
rescue
|
26
|
-
raise Fmt::Error, <<~MSG
|
27
|
-
Invalid filter! #{filter.inspect}
|
28
|
-
Verify it has been properly registered. SEE: Fmt.add_filter(:#{filter.name}, &block)
|
29
|
-
MSG
|
30
|
-
end
|
31
|
-
elsif filter.proc?
|
32
|
-
begin
|
33
|
-
replacement = filter.value.call(replacement)
|
34
|
-
rescue => error
|
35
|
-
raise Fmt::Error, <<~MSG
|
36
|
-
Error in filter! #{filter.inspect}
|
37
|
-
#{error.message}
|
38
|
-
MSG
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
result = string.sub(placeholder, replacement)
|
44
|
-
defined?(Rainbow) ? Rainbow(result) : result
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def transform_embeds(string, **locals)
|
50
|
-
while embeds.any?
|
51
|
-
embed = embeds.shift
|
52
|
-
string = string.sub(embed.placeholder, embed.format(**locals))
|
53
|
-
end
|
54
|
-
string
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|