fop_lang 0.6.0 → 0.7.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.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +76 -34
  3. data/bin/fop +11 -0
  4. data/lib/fop/cli.rb +7 -3
  5. data/lib/fop/version.rb +1 -1
  6. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cfe0a53d59b00d2fc60f0c0f5ed3e413eb61cf0ae445d49562f0cf861cd9f0b
4
- data.tar.gz: 5aa04d8145417d52b42847be17b54a230242143486278d2826adacb7d1143101
3
+ metadata.gz: 798fd7c335f394e878fba2f70a9f60372ea356c79f2dc63392398920d0ffce38
4
+ data.tar.gz: 654786ff77823e8d8dd9a348f958828346e3755e43a04a0f38e711a6c5571ea9
5
5
  SHA512:
6
- metadata.gz: 79efdf103e6e33bc508df356e2295ac49c8f112ad44a0c3aad4209bb204fadcd240b12f14f62ee3266d21762afec1e8a3262b767fda42cc7ebf019688bfbe30e
7
- data.tar.gz: 1f424bf43332438a3f223af0737fa6570de8e06444669edd8808e5d41e2804fe9139598f58336ca098a1b67fba8741519375e3700916747acb8df6ddace3294d
6
+ metadata.gz: 6761f3d7dd602d1c93a2387fc73ea14c11484e88d0d319bbf87df98925977aa15de59a63f23aafffafa384ce3b9def9f81edabae669aabc2012b00d3131e46f4
7
+ data.tar.gz: 7f5187cd510d691dda996284d5a400804b7573f67506701e39a6d2909c8a4026b58655f6b2800708e911377ccce790885a2238eed7a75d4873e4b599d23e67df
data/README.md CHANGED
@@ -1,57 +1,99 @@
1
1
  # fop_lang
2
2
 
3
- Fop (Filter and OPerations language) is an experimental, tiny expression language in the vein of awk and sed. This is a Ruby implementation. It is useful for simultaneously matching and transforming text input.
3
+ Fop (Filter and OPerations language) is a tiny, experimental language for filtering and transforming text. Think of it like awk but with the condition and action segments combined.
4
4
 
5
- ```ruby
6
- gem 'fop_lang'
7
- ```
5
+ This is a Ruby implementation with both a library interface and a bin command.
8
6
 
9
- ## Release Number Example
7
+ ## Installation
10
8
 
11
- This example takes in GitHub branch names, decides if they're release branches, and if so, increments the version number.
9
+ ```bash
10
+ $ gem install fop_lang
11
+ ```
12
+
13
+ You may use fop in a Ruby script:
12
14
 
13
15
  ```ruby
14
- f = Fop('release-{N}.{N+1}.{N=0}')
16
+ require 'fop_lang'
15
17
 
16
- puts f.apply('release-5.99.1')
17
- => 'release-5.100.0'
18
+ f = Fop('foo {N+1}')
18
19
 
19
- puts f.apply('release-5')
20
- => nil
21
- # doesn't match the pattern
20
+ f.apply('foo 1')
21
+ => "foo 2"
22
+
23
+ f.apply('bar 1')
24
+ => nil
25
+ ```
26
+
27
+ or run `fop` from the command line:
28
+
29
+ ```bash
30
+ $ echo 'foo 1' | fop 'foo {N+1}'
31
+ foo 2
32
+ $ echo 'bar 1' | fop 'foo {N+1}'
22
33
  ```
23
34
 
24
- ## Anatomy of a Fop expression
35
+ ## Syntax
36
+
37
+ `Text /(R|r)egex/ {N+1}`
38
+
39
+ The above program demonstrates a text match, a regex match, and a match expression. If the input matches all three segments, output is given. If the input was `Text regex 5`, the output would be `Text regex 6`.
40
+
41
+ ### Text match
42
+
43
+ The input must match this text exactly. Whitespace is part of the match. Wildcards (`*`) are allowed. Special characters (`*/{}\`) may be escaped with `\`.
25
44
 
26
- `Text Literal {Operation}`
45
+ The output of a text match will be the matching input.
27
46
 
28
- The above expression contains the only two parts of Fop (except for the wildcard and escape characters).
47
+ ### Regex match
29
48
 
30
- **Text Literals**
49
+ Regular expressions may be placed between `/`s. If the regular expression contains a `/`, you may escape it with `\`. Special regex characters like `[]()+.*` may also be escaped with `\`.
31
50
 
32
- A text literal works how it sounds: the input must match it exactly. If it matches it passes through unchanged. The only exception is the `*` (wildcard) character, which matches 0 or more of anything. Wildcards can be used anywhere except inside `{...}` (operations).
51
+ The output of a regex match will be the matching input.
33
52
 
34
- If `\` (escape) is used before the special characters `*`, `{` or `}`, then that character is treated like a text literal. It's recommended to use single-quoted Ruby strings with Fop expressions that so you don't need to double-escape.
53
+ ### Match expression
35
54
 
36
- **Operations**
55
+ A match expression both matches on input and modifies that input. An expression is made up of 1 - 3 parts:
37
56
 
38
- Operations are the interesting part of Fop, and are specified between `{` and `}`. An Operation can consist of one to three parts:
57
+ 1. The match, e.g. `N` for numeric.
58
+ 2. The operator, e.g. `+` for addition (optional).
59
+ 3. The argument, e.g `1` for "add one" (required for most operators).
39
60
 
40
- 1. Matching class (required): Defines what characters the operation will match and operate on.
41
- * `N` is the numeric class and will match one or more digits.
42
- * `A` is the alpha class and will match one or more letters (lower or upper case).
43
- * `W` is the word class and matches alphanumeric chars and underscores.
44
- * `*` is the wildcard class and greedily matches everything after it.
45
- * `/.../` matches on the supplied regex between the `/`'s. If you're regex contains a `/`, it must be escaped. Capture groups may be referenced in the operator argument as `$1`, `$2`, etc.
46
- 3. Operator (optional): What to do to the matching characters.
47
- * `=` Replace the matching character(s) with the given argument. If no argument is given, drop the matching chars.
48
- * `>` Append the following chars to the matching value.
49
- * `<` Prepend the following chars to the matching value.
50
- * `+` Perform addition on the matching number and the argument (`N` only).
51
- * `-` Subtract the argument from the matching number (`N` only).
52
- 5. Operator argument (required for some operators): meaning varies by operator.
61
+ The output of a match expression will be the _modified_ matching input. If no operator is given, the output will be the matching input.
62
+
63
+ **Matches**
64
+
65
+ * `N` matches one or more consecutive digits.
66
+ * `A` matches one or more letters (lower or upper case).
67
+ * `W` matches alphanumeric chars and underscores.
68
+ * `*` greedily matches everything after it.
69
+ * `/regex/` matches on the supplied regex. Capture groups may be referenced in the argument as `$1`, `$2`, etc.
70
+
71
+ **Operators**
72
+
73
+ * `=` Replace the matching character(s) with the given argument. If no argument is given, drop the matching chars.
74
+ * `>` Append the argument to the matching value.
75
+ * `<` Prepend the argument to the matching value.
76
+ * `+` Perform addition on the matching number and the argument (`N` only).
77
+ * `-` Subtract the argument from the matching number (`N` only).
78
+
79
+ ## Examples
80
+
81
+ ### Release Number Example
82
+
83
+ This example takes in GitHub branch names, decides if they're release branches, and if so, increments the version number.
84
+
85
+ ```ruby
86
+ f = Fop('release-{N}.{N+1}.{N=0}')
87
+
88
+ puts f.apply('release-5.99.1')
89
+ => 'release-5.100.0'
90
+
91
+ puts f.apply('release-5')
92
+ => nil
93
+ # doesn't match the pattern
94
+ ```
53
95
 
54
- ## More Examples
96
+ ### More Examples
55
97
 
56
98
  ```ruby
57
99
  f = Fop('release-{N=5}.{N+1}.{N=0}')
data/bin/fop CHANGED
@@ -7,7 +7,18 @@ require 'fop_lang'
7
7
  require 'fop/cli'
8
8
 
9
9
  opts = Fop::CLI.options!
10
+
11
+ if opts.version
12
+ puts Fop::VERSION
13
+ exit 0
14
+ end
15
+
10
16
  src = opts.src.read.chomp
17
+ if src.empty?
18
+ $stderr.puts "No expression given"
19
+ exit 1
20
+ end
21
+
11
22
  fop, errors = Fop.compile(src)
12
23
  opts.src.close
13
24
  NL = "\n".freeze
data/lib/fop/cli.rb CHANGED
@@ -2,7 +2,7 @@ require 'optparse'
2
2
 
3
3
  module Fop
4
4
  module CLI
5
- Options = Struct.new(:src, :check, :quiet)
5
+ Options = Struct.new(:src, :check, :quiet, :version)
6
6
 
7
7
  def self.options!
8
8
  options = Options.new
@@ -18,12 +18,16 @@ module Fop
18
18
  options.check = true
19
19
  end
20
20
 
21
- opts.on("-q", "--quiet") do
21
+ opts.on("-q", "--quiet", "Only print errors and output") do
22
22
  options.quiet = true
23
23
  end
24
+
25
+ opts.on("--version", "Print version and exit") do
26
+ options.version = true
27
+ end
24
28
  end.parse!
25
29
 
26
- options.src ||= StringIO.new(ARGV.shift)
30
+ options.src ||= StringIO.new(ARGV.shift || "")
27
31
  options
28
32
  end
29
33
  end
data/lib/fop/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Fop
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fop_lang
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Hollinger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-20 00:00:00.000000000 Z
11
+ date: 2021-08-30 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A micro expression language for Filter and OPerations on text
14
14
  email: jordan.hollinger@gmail.com