ngworder 0.1.1 → 0.1.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 +4 -4
- data/README.md +4 -3
- data/lib/ngworder/version.rb +1 -1
- data/lib/ngworder.rb +72 -10
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 58b3776df5c32d087309ec1988bc4fdb20627dc5140f66833ed2e6fed8d6e828
|
|
4
|
+
data.tar.gz: 5cc6fbd146932a83bef18dd91f3c939ca9d7f4bb99b7270ccd29ebb27664b630
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c628c99ca4def6086d7c1df8ccb927bcea84cb89901c967d3c1eb03a6c58b5dd0d107359118fd85e033cad7a2a0ada609b1e74d6d8d7f0a287e805c43e737ece
|
|
7
|
+
data.tar.gz: 755cb4ea9bc96a0bd62f5f40acba64d1d2c8b0fb838a8ea80eb00bb3d42753bb840ddb45e77be94cd6a5d04bbf8ca980a730a81b4cc971fe9e0dd17cf92fa850
|
data/README.md
CHANGED
|
@@ -4,8 +4,7 @@ Simple CLI to extract NG words from Japanese text using a plain text rules file.
|
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
```
|
|
7
|
-
gem
|
|
8
|
-
gem install ./ngworder-0.1.0.gem
|
|
7
|
+
gem install ngworder
|
|
9
8
|
```
|
|
10
9
|
|
|
11
10
|
## Usage
|
|
@@ -13,6 +12,8 @@ gem install ./ngworder-0.1.0.gem
|
|
|
13
12
|
ngworder target.md
|
|
14
13
|
ngworder --rule=NGWORDS.txt target.md
|
|
15
14
|
ngworder --rg target.md
|
|
15
|
+
ngworder --no-line target.md
|
|
16
|
+
ngworder --color=auto target.md
|
|
16
17
|
ngworder --help
|
|
17
18
|
```
|
|
18
19
|
|
|
@@ -37,7 +38,7 @@ Example:
|
|
|
37
38
|
|
|
38
39
|
## Output
|
|
39
40
|
```
|
|
40
|
-
path/to/file:line:col match
|
|
41
|
+
path/to/file:line:col match # comment
|
|
41
42
|
```
|
|
42
43
|
|
|
43
44
|
## Performance
|
data/lib/ngworder/version.rb
CHANGED
data/lib/ngworder.rb
CHANGED
|
@@ -5,17 +5,18 @@ require "tempfile"
|
|
|
5
5
|
require_relative "ngworder/version"
|
|
6
6
|
|
|
7
7
|
module Ngworder
|
|
8
|
-
Rule = Struct.new(:matcher, :label, :excludes)
|
|
8
|
+
Rule = Struct.new(:matcher, :label, :excludes, :comment)
|
|
9
9
|
Matcher = Struct.new(:type, :pattern, :label)
|
|
10
10
|
|
|
11
11
|
module Parser
|
|
12
12
|
module_function
|
|
13
13
|
|
|
14
|
-
def
|
|
14
|
+
def split_comment(line)
|
|
15
15
|
out = +""
|
|
16
16
|
escaped = false
|
|
17
|
+
comment = nil
|
|
17
18
|
|
|
18
|
-
line.each_char do |ch|
|
|
19
|
+
line.each_char.with_index do |ch, idx|
|
|
19
20
|
if escaped
|
|
20
21
|
out << ch
|
|
21
22
|
escaped = false
|
|
@@ -28,12 +29,15 @@ module Ngworder
|
|
|
28
29
|
next
|
|
29
30
|
end
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
if ch == "#"
|
|
33
|
+
comment = line[(idx + 1)..-1]
|
|
34
|
+
break
|
|
35
|
+
end
|
|
32
36
|
|
|
33
37
|
out << ch
|
|
34
38
|
end
|
|
35
39
|
|
|
36
|
-
out
|
|
40
|
+
[out, comment]
|
|
37
41
|
end
|
|
38
42
|
|
|
39
43
|
def split_unescaped_bang(line)
|
|
@@ -127,7 +131,7 @@ module Ngworder
|
|
|
127
131
|
rules = []
|
|
128
132
|
|
|
129
133
|
File.readlines(path, chomp: true).each do |line|
|
|
130
|
-
content =
|
|
134
|
+
content, comment = split_comment(line)
|
|
131
135
|
next if content.strip.empty?
|
|
132
136
|
|
|
133
137
|
parts = split_unescaped_bang(content)
|
|
@@ -135,7 +139,9 @@ module Ngworder
|
|
|
135
139
|
next unless base
|
|
136
140
|
|
|
137
141
|
excludes = parts.map { |part| parse_matcher(part, trim: :both) }.compact
|
|
138
|
-
|
|
142
|
+
comment = comment&.strip
|
|
143
|
+
comment = nil if comment.nil? || comment.empty?
|
|
144
|
+
rules << Rule.new(base, base.label, excludes, comment)
|
|
139
145
|
end
|
|
140
146
|
|
|
141
147
|
rules
|
|
@@ -225,6 +231,8 @@ module Ngworder
|
|
|
225
231
|
opts.banner = "Usage: ngworder [--rule=NGWORDS.txt] <files...>"
|
|
226
232
|
opts.on("--rule=PATH", "Rules file path (default: NGWORDS.txt)") { |value| options[:rule] = value }
|
|
227
233
|
opts.on("--rg", "Use ripgrep for literal-only prefiltering") { options[:rg] = true }
|
|
234
|
+
opts.on("--[no-]line", "Print the entire line after each match") { |value| options[:line] = value }
|
|
235
|
+
opts.on("--color=MODE", "Colorize matches (auto, always, never)") { |value| options[:color] = value }
|
|
228
236
|
opts.on("-h", "--help", "Show help") do
|
|
229
237
|
puts opts
|
|
230
238
|
return 0
|
|
@@ -247,6 +255,48 @@ module Ngworder
|
|
|
247
255
|
rules = Parser.build_rules(rule_path)
|
|
248
256
|
warn "No rules loaded from #{rule_path}" if rules.empty?
|
|
249
257
|
|
|
258
|
+
line_enabled = options.key?(:line) ? options[:line] : true
|
|
259
|
+
|
|
260
|
+
color_mode = (options[:color] || "auto").downcase
|
|
261
|
+
unless %w[auto always never].include?(color_mode)
|
|
262
|
+
warn "Invalid color mode: #{color_mode} (use auto, always, or never)"
|
|
263
|
+
return 2
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
color_enabled = case color_mode
|
|
267
|
+
when "always"
|
|
268
|
+
true
|
|
269
|
+
when "never"
|
|
270
|
+
false
|
|
271
|
+
else
|
|
272
|
+
$stdout.tty?
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
colorize_match = lambda do |text|
|
|
276
|
+
return text unless color_enabled
|
|
277
|
+
|
|
278
|
+
"\e[35m#{text}\e[0m"
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
colorize_path = lambda do |text|
|
|
282
|
+
return text unless color_enabled
|
|
283
|
+
|
|
284
|
+
"\e[36m#{text}\e[0m"
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
highlight_line = lambda do |line, span|
|
|
288
|
+
return line unless color_enabled
|
|
289
|
+
|
|
290
|
+
start_idx = span[0]
|
|
291
|
+
end_idx = span[1]
|
|
292
|
+
head = line[0, start_idx]
|
|
293
|
+
mid = line[start_idx, end_idx - start_idx]
|
|
294
|
+
tail = line[end_idx..-1]
|
|
295
|
+
return line if mid.nil?
|
|
296
|
+
|
|
297
|
+
"#{head}\e[35m#{mid}\e[0m#{tail}"
|
|
298
|
+
end
|
|
299
|
+
|
|
250
300
|
found = false
|
|
251
301
|
|
|
252
302
|
argv.each do |path|
|
|
@@ -284,7 +334,11 @@ module Ngworder
|
|
|
284
334
|
|
|
285
335
|
found = true
|
|
286
336
|
col_no = span[0] + 1
|
|
287
|
-
|
|
337
|
+
match_text = colorize_match.call(span[2])
|
|
338
|
+
suffix = rule.comment ? " # #{rule.comment}" : ""
|
|
339
|
+
path_text = colorize_path.call(path)
|
|
340
|
+
puts "#{path_text}:#{line_no}:#{col_no} #{match_text}#{suffix}"
|
|
341
|
+
puts highlight_line.call(line, span) if line_enabled
|
|
288
342
|
end
|
|
289
343
|
end
|
|
290
344
|
end
|
|
@@ -312,7 +366,11 @@ module Ngworder
|
|
|
312
366
|
|
|
313
367
|
found = true
|
|
314
368
|
col_no = span[0] + 1
|
|
315
|
-
|
|
369
|
+
match_text = colorize_match.call(span[2])
|
|
370
|
+
suffix = rule.comment ? " # #{rule.comment}" : ""
|
|
371
|
+
path_text = colorize_path.call(path)
|
|
372
|
+
puts "#{path_text}:#{line_no}:#{col_no} #{match_text}#{suffix}"
|
|
373
|
+
puts highlight_line.call(line, span) if line_enabled
|
|
316
374
|
end
|
|
317
375
|
end
|
|
318
376
|
|
|
@@ -329,7 +387,11 @@ module Ngworder
|
|
|
329
387
|
|
|
330
388
|
found = true
|
|
331
389
|
col_no = span[0] + 1
|
|
332
|
-
|
|
390
|
+
match_text = colorize_match.call(span[2])
|
|
391
|
+
suffix = rule.comment ? " # #{rule.comment}" : ""
|
|
392
|
+
path_text = colorize_path.call(path)
|
|
393
|
+
puts "#{path_text}:#{line_no}:#{col_no} #{match_text}#{suffix}"
|
|
394
|
+
puts highlight_line.call(line, span) if line_enabled
|
|
333
395
|
end
|
|
334
396
|
end
|
|
335
397
|
end
|