fmt 0.3.2 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5cab8d0eef24b2446c187520bd8a8ac2b71cef4149ff6d0370ffd04d67120d1
4
- data.tar.gz: 3e5b6dca4adf86661850769bd7ca0191fe7f9b62b7c7c8612765bb5c5fb54c0b
3
+ metadata.gz: ed2f5a4d3984f777c398dfe2efeba95883d1474165b0831cea8b045c9d1bc3d3
4
+ data.tar.gz: 3ae71397daf558b9d32b5377d29f40a2b307a650fc53d08f4faa3cc69759eedb
5
5
  SHA512:
6
- metadata.gz: ceeb6ab3f6d47a8863a35b90addf52135d31905be200c402819a516fa2600bbc0672e03d813555031bee131c865d44a92f3ad431863a3a4efd72ebe7ed3b7cc3
7
- data.tar.gz: cfdbbdb355a735235b7417bc5b96a636c7e4392d8911178fbaa80e16a7127db41d388101cbdb8e14aa15c1562846d83a8546b8137c35cca3ade24aa695e39435
6
+ metadata.gz: e87abb12eb2ff4373ec7f13ecd1ac236b01914296a9d2b854f8bb60dd1aef5ee1e834ba45601a9997fe53168260c5ac33f70c78c694c45c1bc49f5c958cb8e61
7
+ data.tar.gz: d26316457a56992b65d8b9c2d2478b36fc9cdd378a454748a2016dfb2c388de91098f73a5cdce23d3d9dc6d8f0d4d47ac8774c66038c39fdcca10adfedec83bb
data/README.md CHANGED
@@ -1,6 +1,15 @@
1
1
  <p align="center">
2
2
  <a href="http://blog.codinghorror.com/the-best-code-is-no-code-at-all/">
3
- <img alt="Lines of Code" src="https://img.shields.io/badge/loc-1042-47d299.svg" />
3
+ <img alt="Lines of Code" src="https://img.shields.io/badge/loc-1050-47d299.svg" />
4
+ </a>
5
+ <a href="https://rubygems.org/gems/fmt">
6
+ <img alt="GEM Version" src="https://img.shields.io/gem/v/fmt">
7
+ </a>
8
+ <a href="https://rubygems.org/gems/fmt">
9
+ <img alt="GEM Downloads" src="https://img.shields.io/gem/dt/fmt">
10
+ </a>
11
+ <a href="https://github.com/hopsoft/fmt/actions">
12
+ <img alt="Tests" src="https://github.com/hopsoft/fmt/actions/workflows/tests.yml/badge.svg" />
4
13
  </a>
5
14
  <a href="https://github.com/testdouble/standard">
6
15
  <img alt="Ruby Style" src="https://img.shields.io/badge/style-standard-168AFE?logo=ruby&logoColor=FE1616" />
@@ -21,21 +30,21 @@
21
30
 
22
31
  ## Table of Contents
23
32
 
24
- - [Getting Started](#getting-started)
25
- - [Usage](#usage)
26
- - [Macros](#macros)
27
- - [Pipelines](#pipelines)
28
- - [Supported Methods](#supported-methods)
29
- - [Rainbow GEM](#rainbow-gem)
30
- - [Composition](#composition)
31
- - [Embedded Templates](#embedded-templates)
32
- - [Customizing Fmt](#customizing-fmt)
33
- - [Kernel Refinement](#kernel-refinement)
34
- - [`fmt(object, *pipeline)`](#fmtobject-pipeline)
35
- - [`fmt_print(object, *pipeline)`](#fmt_printobject-pipeline)
36
- - [`fmt_puts(object, *pipeline)`](#fmt_putsobject-pipeline)
37
- - [Performance](#performance)
38
- - [Sponsors](#sponsors)
33
+ - [Getting Started](#getting-started)
34
+ - [Usage](#usage)
35
+ - [Macros](#macros)
36
+ - [Pipelines](#pipelines)
37
+ - [Supported Methods](#supported-methods)
38
+ - [Rainbow GEM](#rainbow-gem)
39
+ - [Composition](#composition)
40
+ - [Embedded Templates](#embedded-templates)
41
+ - [Customizing Fmt](#customizing-fmt)
42
+ - [Kernel Refinement](#kernel-refinement)
43
+ - [`fmt(object, *pipeline)`](#fmtobject-pipeline)
44
+ - [`fmt_print(object, *pipeline)`](#fmt_printobject-pipeline)
45
+ - [`fmt_puts(object, *pipeline)`](#fmt_putsobject-pipeline)
46
+ - [Performance](#performance)
47
+ - [Sponsors](#sponsors)
39
48
 
40
49
  <!-- Tocer[finish]: Auto-generated, don't remove. -->
41
50
 
@@ -133,7 +142,7 @@ Templates can include multiple format strings with distinct pipelines:
133
142
  ```ruby
134
143
  template = "Date: %<date>.10s|>magenta -- %{msg}|>titleize|>bold"
135
144
  Fmt(template, date: Time.now, msg: "this is cool")
136
- #=> "Date: \e[35m2024-09-20\e[0m \e[1mThis Is Cool\e[0m"
145
+ #=> "Date: \e[35m2024-09-21\e[0m -- \e[1mThis Is Cool\e[0m"
137
146
  ```
138
147
 
139
148
  #### Embedded Templates
@@ -178,11 +187,11 @@ template = <<~T
178
187
  %{one}|>red {{
179
188
  %{two}|>blue {{
180
189
  %{three}|>green
181
- }}
182
- }}|>bold
190
+ }}|>bold
191
+ }}
183
192
  T
184
193
  Fmt(template, one: "Red", two: "Blue", three: "Green")
185
- #=> "Multiline:\n\e[31mRed\e[0m \e[1m\n \e[34mBlue\e[0m \n \e[32mGreen\e[0m"
194
+ #=> "Multiline:\n\e[31mRed\e[0m \n \e[34mBlue\e[0m \e[1m\n \e[32mGreen\e[0m\n \e[0m\n\n"
186
195
  ```
187
196
 
188
197
  ### Customizing Fmt
@@ -6,9 +6,9 @@ module Fmt
6
6
  # Parses a template from a string and builds an AST (Abstract Syntax Tree)
7
7
  class TemplateParser < Parser
8
8
  EMBED_PEEK = %r{(?=#{esc Sigils::EMBED_PREFIX})}o # : Regexp -- detects start of an embed prefix (look ahead)
9
- PIPELINE_HEAD = %r{[#{Sigils::FORMAT_PREFIX}]}o # : Regexp -- detects start of a pipeline (i.e. Ruby format string)
10
- PIPELINE_PEEK = %r{(?=[#{Sigils::FORMAT_PREFIX}][^#{Sigils::FORMAT_PREFIX}]|\z)}o # : Regexp -- detects start of a pipeline (look ahead)
11
- PIPELINE_TAIL = %r{\s|\z}o # : Regexp -- detects end of a pipeline
9
+ PIPELINE_PEEK = %r{(?=[#{Sigils::FORMAT_PREFIX}][^#{Sigils::FORMAT_PREFIX}])}o # : Regexp -- detects start of a pipeline (look ahead)
10
+ PERCENT_LITERAL = %r{[#{Sigils::FORMAT_PREFIX}]{2}}o # : Regexp -- detects a percent literal
11
+ WHITESPACE = %r{\s}o # : Regexp -- detects whitespace
12
12
 
13
13
  # Constructor
14
14
  # @rbs urtext: String -- original source code
@@ -66,48 +66,28 @@ module Fmt
66
66
  # Extracts the next embed with the scanner
67
67
  # @rbs scanner: StringScanner -- scanner to extract from
68
68
  # @rbs return: String? -- extracted embed
69
- # def extract_next_embed(scanner)
70
- # return nil unless scanner.skip_until(EMBED_PEEK)
71
-
72
- # index = scanner.pos
73
- # rindex = index
74
- # stack = 0
75
- # string = scanner.string
76
-
77
- # while rindex < string.length
78
- # char = string.getbyte(rindex)
79
-
80
- # case char
81
- # when Sigils::EMBED_PREFIX.ord then stack += 1
82
- # when Sigils::EMBED_SUFFIX.ord then stack -= 1
83
- # end
84
-
85
- # rindex += 1
86
- # break if stack.zero?
87
- # end
88
-
89
- # stack.zero? ? string[index...rindex] : nil
90
- # end
91
69
  def extract_next_embed(scanner)
92
70
  return nil unless scanner.skip_until(EMBED_PEEK)
93
71
 
94
- string = scanner.string
72
+ head = Sigils::EMBED_PREFIX[0]
73
+ tail = Sigils::EMBED_SUFFIX[0]
95
74
  index = scanner.pos
96
- rindex = index
97
75
  stack = 0
98
76
 
99
- while rindex < string.length
100
- case string[rindex]
101
- in Sigils::EMBED_PREFIX[0] then break if (stack += 1).zero?
102
- in Sigils::EMBED_SUFFIX[0] then break if (stack -= 1).zero?
77
+ until scanner.eos?
78
+ case scanner.getch
79
+ in ^head then stack += 1
80
+ in ^tail then stack -= 1
81
+ in nil then break
103
82
  else # noop
104
83
  end
105
84
 
106
- rindex += 1
85
+ break if stack.zero?
107
86
  end
108
87
 
109
- scanner.pos = rindex
110
- stack.zero? ? string[index...rindex] : nil
88
+ return nil unless stack.zero?
89
+
90
+ scanner.string[index...scanner.pos]
111
91
  end
112
92
 
113
93
  # Extracts embed metadata from the source
@@ -136,12 +116,25 @@ module Fmt
136
116
  # @rbs scanner: StringScanner -- scanner to extract from
137
117
  # @rbs return: String? -- extracted pipeline
138
118
  def extract_next_pipeline(scanner)
139
- return nil unless scanner.skip_until(PIPELINE_HEAD)
119
+ return nil unless scanner.skip_until(PIPELINE_PEEK)
140
120
 
141
121
  index = scanner.pos
142
- rindex = scanner.skip_until(PIPELINE_PEEK) ? scanner.pos : scanner.terminate.pos
143
- pipeline = scanner.string[index - 1...rindex].strip
144
- pipeline.rpartition(PIPELINE_TAIL).first
122
+
123
+ until scanner.eos?
124
+ if scanner.peek(2).match?(PERCENT_LITERAL)
125
+ scanner.pos += 2
126
+ next
127
+ end
128
+
129
+ case [index, scanner.pos, scanner.peek(1)]
130
+ in [i, pos, Sigils::FORMAT_PREFIX] if i == pos then scanner.pos += 1
131
+ in [i, pos, Sigils::FORMAT_PREFIX] if i != pos then break
132
+ in [i, pos, WHITESPACE] if arguments_balanced?(scanner.string[i...pos]) then break
133
+ else scanner.pos += 1
134
+ end
135
+ end
136
+
137
+ scanner.string[index...scanner.pos]
145
138
  end
146
139
 
147
140
  # Extracts pipelines from the source
@@ -158,5 +151,13 @@ module Fmt
158
151
 
159
152
  generator.to_a
160
153
  end
154
+
155
+ # Indicates if arguments are balances in the given list of chars
156
+ # @rbs value: String -- value to check
157
+ # @rbs return: bool
158
+ def arguments_balanced?(value)
159
+ return true if value.nil? || value.empty?
160
+ value.count(Sigils::ARGS_PREFIX) == value.count(Sigils::ARGS_SUFFIX)
161
+ end
161
162
  end
162
163
  end
data/lib/fmt/version.rb CHANGED
@@ -3,5 +3,5 @@
3
3
  # rbs_inline: enabled
4
4
 
5
5
  module Fmt
6
- VERSION = "0.3.2"
6
+ VERSION = "0.3.3"
7
7
  end
@@ -5,11 +5,11 @@ module Fmt
5
5
  class TemplateParser < Parser
6
6
  EMBED_PEEK: ::Regexp
7
7
 
8
- PIPELINE_HEAD: ::Regexp
9
-
10
8
  PIPELINE_PEEK: ::Regexp
11
9
 
12
- PIPELINE_TAIL: ::Regexp
10
+ PERCENT_LITERAL: ::Regexp
11
+
12
+ WHITESPACE: ::Regexp
13
13
 
14
14
  # Constructor
15
15
  # @rbs urtext: String -- original source code
@@ -35,9 +35,10 @@ module Fmt
35
35
 
36
36
  private
37
37
 
38
- # stack.zero? ? string[index...rindex] : nil
39
- # end
40
- def extract_next_embed: (untyped scanner) -> untyped
38
+ # Extracts the next embed with the scanner
39
+ # @rbs scanner: StringScanner -- scanner to extract from
40
+ # @rbs return: String? -- extracted embed
41
+ def extract_next_embed: (StringScanner scanner) -> String?
41
42
 
42
43
  # Extracts embed metadata from the source
43
44
  # @rbs return: Array[Hash] -- extracted embeds
@@ -52,5 +53,10 @@ module Fmt
52
53
  # @rbs source: String -- source code to extract pipelines from
53
54
  # @rbs return: Array[String] -- extracted pipelines
54
55
  def extract_pipelines: (String source) -> Array[String]
56
+
57
+ # Indicates if arguments are balances in the given list of chars
58
+ # @rbs value: String -- value to check
59
+ # @rbs return: bool
60
+ def arguments_balanced?: (String value) -> bool
55
61
  end
56
62
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fmt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nate Hopkins (hopsoft)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-10 00:00:00.000000000 Z
11
+ date: 2024-10-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ast