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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 889f89130c4888e512729e7cba02a6de8ed641b1d602f11727ffe38ed689609e
4
- data.tar.gz: cd10c6139594e5f4c8b3da5c6a32461f6f122799a6cde7f82a3ad7080a8cd772
3
+ metadata.gz: 58b3776df5c32d087309ec1988bc4fdb20627dc5140f66833ed2e6fed8d6e828
4
+ data.tar.gz: 5cc6fbd146932a83bef18dd91f3c939ca9d7f4bb99b7270ccd29ebb27664b630
5
5
  SHA512:
6
- metadata.gz: 893e15048ef240a304ffee81f1f8ba92a85335227b44eed47de2e11495881d316ea7f0f9c3ea9c2e418c370514b1b88ad7474873761251b1fb51f1ebab2bd2da
7
- data.tar.gz: 528b003d4c2da44561827b70fba0fe50190e825dd634f6ac2fd42d53aaf80aa9d1befab73dcc7673e99caf071e78c1e9f0e3ff4e3bbc9c0f6843e4b6044449d2
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 build ngworder.gemspec
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 NG:<rule>
41
+ path/to/file:line:col match # comment
41
42
  ```
42
43
 
43
44
  ## Performance
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ngworder
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.3"
5
5
  end
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 strip_comment(line)
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
- break if ch == "#"
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 = strip_comment(line)
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
- rules << Rule.new(base, base.label, excludes)
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
- puts "#{path}:#{line_no}:#{col_no} #{span[2]} NG:#{rule.label}"
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
- puts "#{path}:#{line_no}:#{col_no} #{span[2]} NG:#{rule.label}"
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
- puts "#{path}:#{line_no}:#{col_no} #{span[2]} NG:#{rule.label}"
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ngworder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masanori Kado