fop_lang 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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