mk_semi_lattice 0.1.1

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 (36) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.hyper_card/history/20251020_1517_readme_formatted.md +463 -0
  4. data/.hyper_card/history/20251020_1828_minor_rev_formatted.md +181 -0
  5. data/.hyper_card/history/20251021_1110_wsl_ubuntu_japanese.md +218 -0
  6. data/.hyper_card/history/20251021_1142_double_click_action.md +250 -0
  7. data/.hyper_card/history/20251021_1151_select_semi_data_action.md +75 -0
  8. data/.hyper_card/history/20251021_2322_add_comment_edges.md +252 -0
  9. data/.hyper_card/history/20251022_0725_add_color_index.md +155 -0
  10. data/.hyper_card/history/classify_251103.md +1090 -0
  11. data/.hyper_card/history/file_path_modifier.md +481 -0
  12. data/.hyper_card/history/file_path_modifier_251103.md +505 -0
  13. data/.hyper_card/history/knowledge_fixer.pdf +0 -0
  14. data/.hyper_card/history/log_with_symbol_251102.md +184 -0
  15. data/.hyper_card/history/memory_leak_251028.md +311 -0
  16. data/.hyper_card/history/set_log_conf_251027.md +295 -0
  17. data/CHANGELOG.md +5 -0
  18. data/CODE_OF_CONDUCT.md +132 -0
  19. data/LICENSE.txt +21 -0
  20. data/README.md +43 -0
  21. data/Rakefile +8 -0
  22. data/exe/mk_semi_lattice +3 -0
  23. data/exe/sl +5 -0
  24. data/lib/mk_semi_lattice/config.rb +53 -0
  25. data/lib/mk_semi_lattice/log.rb +26 -0
  26. data/lib/mk_semi_lattice/manage_yaml.rb +89 -0
  27. data/lib/mk_semi_lattice/mk_dir_yaml.rb +40 -0
  28. data/lib/mk_semi_lattice/mk_node_edge.rb +108 -0
  29. data/lib/mk_semi_lattice/mk_semi_lattice_graph.rb +254 -0
  30. data/lib/mk_semi_lattice/mk_semi_lattice_viewer.rb +77 -0
  31. data/lib/mk_semi_lattice/option_manager.rb +58 -0
  32. data/lib/mk_semi_lattice/ruby2d_action.rb +136 -0
  33. data/lib/mk_semi_lattice/version.rb +5 -0
  34. data/lib/mk_semi_lattice.rb +22 -0
  35. data/sig/mk_semi_lattice.rbs +4 -0
  36. metadata +122 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fd367913e384f82dbbb7b8db40d35646855a82d5006715a51fc4eaa6601bc0ca
4
+ data.tar.gz: fed2c0e74140c8dd15933c13ec8eb4e6466f72ac8f7f5a899c063046e62a6ce8
5
+ SHA512:
6
+ metadata.gz: b44216e9db854f9a28d5f9b27463f0bfd119aaa0dece1e70cdd4e35c0628ee1c5720d5f780985c35e548c32dd63f71c46af9781e7f35960d3d8ec98b680b6a3f
7
+ data.tar.gz: 8984c903dc85dcdf6e32bf80405d0ef6aae28718c8e776e5496554f385604a30d73bacecda8af54b7b0b6eadaaaae9ce6ef48e48844898de1adc7407f54e4bda
data/.DS_Store ADDED
Binary file
@@ -0,0 +1,463 @@
1
+ # head
2
+ date: 2025-10-20
3
+ author: bob
4
+
5
+ ## User
6
+ module MkSemiLatticeの下に,MkDirYamlクラスを作成し,mk_dir.yaml.rbの動作を実行するようにしてください.
7
+
8
+
9
+ [mk_dir_yaml.rb](./codes/nowledge_fixer.rb)
10
+
11
+ `MkSemiLattice::MkDirYaml` クラスを作成し、コマンドライン処理とディレクトリ構造の出力をクラスメソッドにまとめます。スクリプトの処理は `MkSemiLattice::MkDirYaml.run` で実行されるようにします。
12
+
13
+ ````ruby
14
+ require 'yaml'
15
+ require 'optparse'
16
+
17
+ module MkSemiLattice
18
+ class MkDirYaml
19
+ def self.run(argv)
20
+ options = { layer: 2, output: 'dir.yaml' }
21
+ OptionParser.new do |opts|
22
+ opts.banner = "Usage: ruby mk_dir_yaml.rb PATH [-L layer] [-o output_file]"
23
+ opts.on("-L N", Integer, "Layer depth (default: 2)") { |v| options[:layer] = v }
24
+ opts.on("-o", "--output FILE", "Output file (default: dir.yaml)") { |v| options[:output] = v }
25
+ end.parse!(argv)
26
+
27
+ path = argv[0] || '.'
28
+ output_file = options[:output]
29
+ abs_path = File.expand_path(path)
30
+ root_key = File.basename(abs_path) + '/'
31
+
32
+ result = { root_key => dir_tree(path, options[:layer] - 1) }
33
+ p result
34
+ File.write(output_file, result.to_yaml)
35
+ puts "Directory structure exported to #{output_file}"
36
+ end
37
+
38
+ def self.dir_tree(path, depth)
39
+ return nil if depth < 0
40
+ tree = {}
41
+ Dir.children(path).each do |entry|
42
+ next if entry.start_with?('.')
43
+ full = File.join(path, entry)
44
+ if File.symlink?(full)
45
+ target = File.readlink(full)
46
+ tree[entry] = "-> #{target}"
47
+ elsif File.directory?(full)
48
+ subtree = dir_tree(full, depth - 1)
49
+ if subtree
50
+ tree["#{entry}/"] = subtree
51
+ else
52
+ tree["#{entry}/"] = nil
53
+ end
54
+ else
55
+ tree[entry] = nil
56
+ end
57
+ end
58
+ tree
59
+ end
60
+ end
61
+ end
62
+
63
+ # 実行部分
64
+ if __FILE__ == $0
65
+ MkSemiLattice::MkDirYaml.run(ARGV)
66
+ end
67
+ ````
68
+
69
+ Made changes.
70
+
71
+ ## User
72
+ OptionParserの振る舞いは,mk_semi_lattice.rbに移してください.
73
+
74
+
75
+ [mk_dir_yaml.rb](./codes/nowledge_fixer.rb)
76
+
77
+ `OptionParser` の処理を削除し、`run` メソッドは引数として `path`, `layer`, `output_file` を受け取るようにします。
78
+
79
+ ````ruby
80
+ require 'yaml'
81
+
82
+ module MkSemiLattice
83
+ class MkDirYaml
84
+ def self.run(path: '.', layer: 2, output_file: 'dir.yaml')
85
+ abs_path = File.expand_path(path)
86
+ root_key = File.basename(abs_path) + '/'
87
+
88
+ result = { root_key => dir_tree(path, layer - 1) }
89
+ p result
90
+ File.write(output_file, result.to_yaml)
91
+ puts "Directory structure exported to #{output_file}"
92
+ end
93
+
94
+ def self.dir_tree(path, depth)
95
+ # ...existing code...
96
+ end
97
+ end
98
+ end
99
+
100
+ # 実行部分は削除
101
+ ````
102
+
103
+ ---
104
+
105
+
106
+ [mk_semi_lattice.rb](./codes/nowledge_fixer.rb)
107
+
108
+ `OptionParser` の処理をこのファイルに移し、`MkSemiLattice::MkDirYaml.run` を呼び出します。
109
+
110
+ ````ruby
111
+ require_relative 'lib/mk_semi_lattice/mk_dir_yaml'
112
+ require 'optparse'
113
+
114
+ options = { layer: 2, output: 'dir.yaml' }
115
+ OptionParser.new do |opts|
116
+ opts.banner = "Usage: ruby mk_semi_lattice.rb PATH [-L layer] [-o output_file]"
117
+ opts.on("-L N", Integer, "Layer depth (default: 2)") { |v| options[:layer] = v }
118
+ opts.on("-o", "--output FILE", "Output file (default: dir.yaml)") { |v| options[:output] = v }
119
+ end.parse!
120
+
121
+ path = ARGV[0] || '.'
122
+ MkSemiLattice::MkDirYaml.run(path: path, layer: options[:layer], output_file: options[:output])
123
+ ````
124
+
125
+ Made changes.
126
+
127
+ ## User
128
+ yamlファイルをARGV[0]に指定してきた時には,MkDirYaml.newせずに指定ファイルの中身をcatする.
129
+
130
+
131
+ [mk_semi_lattice.rb](./codes/nowledge_fixer.rb)
132
+
133
+ ARGV[0]が`.yaml`または`.yml`で終わる場合は、そのファイルをcatし、それ以外の場合のみ`MkDirYaml.new`を呼び出すようにします。
134
+
135
+ ````ruby
136
+ # ...existing code...
137
+
138
+ options = { layer: 2, output: 'dir.yaml' }
139
+ OptionParser.new do |opts|
140
+ # ...existing code...
141
+ end.parse!
142
+
143
+ path = ARGV[0] || '.'
144
+
145
+ if path =~ /\.ya?ml\z/
146
+ puts File.read(path)
147
+ else
148
+ semi_dir = File.join(path, '.semi_lattice')
149
+ Dir.mkdir(semi_dir) unless Dir.exist?(semi_dir)
150
+ dir_yaml_path = File.join(semi_dir, 'dir.yaml')
151
+ MkSemiLattice::MkDirYaml.new(path: path, layer: options[:layer], output_file: dir_yaml_path)
152
+ end
153
+
154
+ # ...existing code...
155
+ ````
156
+
157
+ Made changes.
158
+
159
+ ## User
160
+ dir.yamlを読み込んで,traverse関数を使ったnode_edgeのHashを作り,結果をdir_node_edge.yamlに保存するclass MkNodeEdgeをmodule SemiLattiiceの下に作成する.
161
+
162
+
163
+ [mk_node_edge.rb](./codes/nowledge_fixer.rb)
164
+
165
+ `SemiLattice::MkNodeEdge` クラスを作成し、dir.yaml を読み込んでノード・エッジ情報を生成し、`dir_node_edge.yaml` に保存する処理をクラスメソッドとしてまとめます。
166
+
167
+ ````ruby
168
+ require 'yaml'
169
+ require 'pathname'
170
+
171
+ module SemiLattice
172
+ class MkNodeEdge
173
+ def self.run(input_path:, output_path:)
174
+ dir_tree = YAML.load_file(input_path)
175
+ nodes = []
176
+ edges = []
177
+ id_counter = { val: 1 }
178
+ id_name_map = {}
179
+
180
+ root_name = dir_tree.keys.first
181
+ top_path = root_name
182
+ traverse(dir_tree, nil, nodes, edges, id_counter, id_name_map, '.', top_path)
183
+
184
+ output = { 'nodes' => nodes, 'edges' => edges }
185
+ yaml_str = output.to_yaml
186
+
187
+ # コメント追加
188
+ yaml_lines = yaml_str.lines
189
+ new_yaml_lines = []
190
+ edges_section = false
191
+ edges_idx = 0
192
+ edges_count = edges.size
193
+
194
+ yaml_lines.each do |line|
195
+ new_yaml_lines << line
196
+ if line.strip == 'edges:'
197
+ edges_section = true
198
+ next
199
+ end
200
+ if edges_section && line.strip.start_with?('- from:')
201
+ edge = edges[edges_idx]
202
+ from_name = id_name_map[edge['from']]
203
+ to_name = id_name_map[edge['to']]
204
+ comment = "# from: #{from_name}, to: #{to_name}"
205
+ new_yaml_lines << " #{comment}\n"
206
+ edges_idx += 1
207
+ edges_section = false if edges_idx >= edges_count
208
+ end
209
+ end
210
+
211
+ File.write(output_path, new_yaml_lines.join)
212
+ end
213
+
214
+ def self.traverse(node, parent_id, nodes, edges, id_counter, id_name_map, current_path, top_path)
215
+ # ...existing code for traverse...
216
+ if node.is_a?(Hash)
217
+ node.each do |name, value|
218
+ node_id = id_counter[:val]
219
+ id_counter[:val] += 1
220
+
221
+ type = value.is_a?(Hash) || value.is_a?(Array) ? 'dir' : 'file'
222
+ p [current_path, name]
223
+ node_path = File.join(current_path, name.to_s)
224
+ rel_path = if node_path == top_path
225
+ '.'
226
+ else
227
+ rp = Pathname.new(node_path).relative_path_from(Pathname.new(top_path)).to_s
228
+ rp.start_with?('.') ? rp : "./#{rp}"
229
+ end
230
+
231
+ nodes << {
232
+ 'id' => node_id,
233
+ 'name' => name,
234
+ 'type' => type,
235
+ 'file_path' => rel_path
236
+ }
237
+ id_name_map[node_id] = name
238
+ if parent_id
239
+ edges << {
240
+ 'from' => parent_id,
241
+ 'to' => node_id
242
+ }
243
+ end
244
+
245
+ if value.is_a?(Hash) || value.is_a?(Array)
246
+ traverse(value, node_id, nodes, edges, id_counter, id_name_map, node_path, top_path)
247
+ end
248
+ end
249
+ elsif node.is_a?(Array)
250
+ node.each do |item|
251
+ traverse(item, parent_id, nodes, edges, id_counter, id_name_map, current_path, top_path)
252
+ end
253
+ end
254
+ end
255
+ end
256
+ end
257
+
258
+ # 実行部分例(必要なら有効化)
259
+ # if __FILE__ == $0
260
+ # input_path = File.join(File.dirname(__FILE__), '.semi_lattice', 'dir.yaml')
261
+ # output_path = File.join(File.dirname(__FILE__), '.semi_lattice', 'dir_node_edge.yaml')
262
+ # SemiLattice::MkNodeEdge.run(input_path: input_path, output_path: output_path)
263
+ # end
264
+ ````
265
+
266
+ Made changes.
267
+
268
+ ## User
269
+ #terminalSelection というerrorが出ます.
270
+
271
+ ## Copilot
272
+ Read terminal selection
273
+
274
+
275
+ [mk_semi_lattice.rb](./codes/nowledge_fixer.rb)
276
+
277
+ `MkNodeEdge` は `SemiLattice::MkNodeEdge` です。
278
+ また、`MkDirYaml` も `MkSemiLattice::MkDirYaml` です。
279
+ クラス名の修正と、`dir_yaml_path` のスコープ修正を行います。
280
+
281
+ ````ruby
282
+ # ...existing code...
283
+
284
+ path = ARGV[0] || '.'
285
+
286
+ if path =~ /\.ya?ml\z/
287
+ puts File.read(path)
288
+ else
289
+ semi_dir = File.join(path, '.semi_lattice')
290
+ Dir.mkdir(semi_dir) unless Dir.exist?(semi_dir)
291
+ dir_yaml_path = File.join(semi_dir, 'dir.yaml')
292
+ MkSemiLattice::MkDirYaml.new(path: path, layer: options[:layer], output_file: dir_yaml_path)
293
+ # node_edge生成はdir.yaml作成時のみ
294
+ SemiLattice::MkNodeEdge.run(
295
+ input_path: dir_yaml_path,
296
+ output_path: File.join(semi_dir, 'dir_node_edge.yaml')
297
+ )
298
+ end
299
+
300
+ # ...existing code...
301
+ ````
302
+
303
+ **ポイント:**
304
+ - `MkSemiLattice::MkDirYaml` と `SemiLattice::MkNodeEdge` の名前空間を正しく指定。
305
+ - `MkNodeEdge.new` ではなく `SemiLattice::MkNodeEdge.run` を呼び出す。
306
+ - `dir_yaml_path` は else 節内でのみ有効なので、その中で node_edge 生成も行う。
307
+
308
+ Made changes.
309
+
310
+ ## User
311
+ /Users/bob/git_hub/mk_semi_lattice/lib/mk_semi_lattice.rb:39:in `<top (required)>': undefined method `semi_dir' for MkSemiLattice:Module (NoMethodError)
312
+ とのerrorが出ます.semi_dirをうまく取り出す方法はありますか?
313
+
314
+
315
+ [mk_semi_lattice.rb](./codes/nowledge_fixer.rb)
316
+
317
+ `semi_dir` は `else` 節内でしか定義されていません。
318
+ グラフ部分でも使いたい場合は、`semi_dir` を `path` から導出して再定義するか、
319
+ `dir_node_edge.yaml` のパスを明示的に指定してください。
320
+
321
+ 下記は `semi_dir` を `path` から導出して再利用する例です。
322
+
323
+ ````ruby
324
+ # ...existing code...
325
+
326
+ path = ARGV[0] || '.'
327
+ semi_dir = File.join(path, '.semi_lattice')
328
+
329
+ if path =~ /\.ya?ml\z/
330
+ puts File.read(path)
331
+ else
332
+ Dir.mkdir(semi_dir) unless Dir.exist?(semi_dir)
333
+ dir_yaml_path = File.join(semi_dir, 'dir.yaml')
334
+ MkSemiLattice::MkDirYaml.new(path: path, layer: options[:layer], output_file: dir_yaml_path)
335
+ SemiLattice::MkNodeEdge.run(
336
+ input_path: dir_yaml_path,
337
+ output_path: File.join(semi_dir, 'dir_node_edge.yaml')
338
+ )
339
+ end
340
+
341
+ file = ARGV[0] || File.join(semi_dir, "dir_node_edge.yaml")
342
+ app = MkSemiLatticeData.new(file)
343
+
344
+ # ...existing code...
345
+ ````
346
+
347
+ **ポイント:**
348
+ - `semi_dir` を `path` から常に導出することで、どこでも使えるようにします。
349
+ - `file = ARGV[0] || File.join(semi_dir, "dir_node_edge.yaml")` で `semi_dir` を利用できます。
350
+
351
+ Made changes.
352
+
353
+ ## User
354
+ pathを実行dirに設定してください.
355
+
356
+
357
+ [mk_semi_lattice.rb](./codes/nowledge_fixer.rb)
358
+
359
+ `path` を実行ディレクトリ(`Dir.pwd`)に設定します。
360
+ `ARGV[0]` が `.yaml` の場合はそのファイルをcatし、それ以外は `Dir.pwd` を使って処理します。
361
+
362
+ ````ruby
363
+ # ...existing code...
364
+
365
+ options = { layer: 2, output: 'dir.yaml' }
366
+ OptionParser.new do |opts|
367
+ # ...existing code...
368
+ end.parse!
369
+
370
+ # pathを実行ディレクトリに設定
371
+ path = Dir.pwd
372
+
373
+ if ARGV[0] && ARGV[0] =~ /\.ya?ml\z/
374
+ puts File.read(ARGV[0])
375
+ file = ARGV[0]
376
+ else
377
+ $semi_dir = File.join(path, '.semi_lattice')
378
+ Dir.mkdir($semi_dir) unless Dir.exist?($semi_dir)
379
+ dir_yaml_path = File.join($semi_dir, 'dir.yaml')
380
+ MkDirYaml.new(path: path, layer: options[:layer], output_file: dir_yaml_path)
381
+ MkNodeEdge.new(input_path: dir_yaml_path, output_path: File.join($semi_dir, 'dir_node_edge.yaml'))
382
+ file = File.join($semi_dir, "dir_node_edge.yaml")
383
+ end
384
+
385
+ app = MkSemiLatticeData.new(file)
386
+
387
+ # ...existing code...
388
+ ````
389
+
390
+ Made changes.
391
+
392
+ ## User
393
+ #terminalSelection というエラーが出ます.
394
+
395
+ ## Copilot
396
+ Read terminal selection
397
+
398
+
399
+ [mk_semi_lattice.rb](./codes/nowledge_fixer.rb)
400
+
401
+ エラーの原因は、`at_exit` で .semi_lattice ディレクトリが存在しない場合にファイルを書き込もうとしているためです。
402
+ `at_exit` 内で .semi_lattice ディレクトリの存在を確認し、なければ作成してください。
403
+
404
+ ````ruby
405
+ # ...existing code...
406
+
407
+ at_exit do
408
+ semi_lattice_dir = File.join(File.dirname(__FILE__), '.semi_lattice')
409
+ Dir.mkdir(semi_lattice_dir) unless Dir.exist?(semi_lattice_dir)
410
+ nodes_data = app.nodes.map do |n|
411
+ {
412
+ id: app.node_table.key(n),
413
+ name: n.label,
414
+ type: n.type,
415
+ file_path: n.file_path,
416
+ x: n.x,
417
+ y: n.y,
418
+ fixed: n.fixed
419
+ }
420
+ end
421
+ edges_data = app.edges.map do |e|
422
+ {
423
+ from: app.node_table.key(e.from),
424
+ to: app.node_table.key(e.to)
425
+ }
426
+ end
427
+ yaml_data = { nodes: nodes_data, edges: edges_data }
428
+ File.write(File.join(semi_lattice_dir, "semi_lattice.yaml"), YAML.dump(yaml_data))
429
+ end
430
+
431
+ # ...existing code...
432
+ ````
433
+
434
+ Made changes.
435
+
436
+ ## User knowledgeのためのsemi_lattice作成
437
+ directoryではなく,knowledgeのためのsemi_lattice作成に拡張.
438
+ copilotでは時間がかかりそうなので,手動で.
439
+
440
+ ````ruby
441
+ path = ARGV[0] || '.'
442
+ $semi_dir = File.join(path, '.semi_lattice')
443
+ if path == '.'
444
+ Dir.mkdir($semi_dir) unless Dir.exist?($semi_dir)
445
+ dir_yaml_path = File.join($semi_dir, 'dir.yaml')
446
+ MkSemiLattice::MkDirYaml.new(path: path, layer: options[:layer], output_file: dir_yaml_path)
447
+ MkSemiLattice::MkNodeEdge.new(input_path: dir_yaml_path, output_path: File.join($semi_dir, 'dir_node_edge.yaml'))
448
+ end
449
+
450
+ ... existing codes
451
+
452
+ t_exit do
453
+ Dir.mkdir($semi_dir) unless
454
+
455
+ ... existing codes
456
+
457
+ yaml_data = { nodes: nodes_data, edges: edges_data }
458
+ if Dir.exist?($semi_dir)
459
+ File.write(File.join($semi_dir, "semi_lattice.yaml"), YAML.dump(yaml_data))
460
+ else
461
+ File.write(File.join('.', "semi_lattice.yaml"), YAML.dump(yaml_data))
462
+ end
463
+ end
@@ -0,0 +1,181 @@
1
+ # head
2
+ date: 2025-10-20
3
+ author: bob
4
+
5
+ ## User
6
+ .semi_lattice/semi_lattice.yamlが存在する場合にも,ノード座標・fixed状態を反映
7
+
8
+
9
+ [mk_semi_lattice.rb](./codes/nowledge_fixer.rb)
10
+
11
+ 変更内容:
12
+ `.semi_lattice/semi_lattice.yaml` が存在する場合にもノード座標・fixed状態を反映するように、ファイル存在チェックを追加します。
13
+
14
+ ````ruby
15
+ # ...existing code...
16
+
17
+ file = ARGV[0] || File.join($semi_dir, "dir_node_edge.yaml")
18
+
19
+ semi_lattice_yaml_path = File.join($semi_dir, "semi_lattice.yaml")
20
+ if file =~ /semi_lattice\.ya?ml\z/ || File.exist?(semi_lattice_yaml_path)
21
+ # semi_lattice.yamlが指定された場合、または存在する場合はノード座標・fixed状態を反映
22
+ app = MkSemiLatticeData.new(file =~ /semi_lattice\.ya?ml\z/ ? file : semi_lattice_yaml_path, with_semi_lattice_yaml: true)
23
+ else
24
+ app = MkSemiLatticeData.new(file)
25
+ end
26
+
27
+ # ...existing code...
28
+ ````
29
+
30
+ Made changes.
31
+
32
+ ## User
33
+ ARGV[0]でsemi_lattice.yamlが指定された場合,あるいは'.semi_lattice/sem_lattice.yaml'が存在する場合はwith_semi_lattice_yaml: trueでMkSemiLatticeData.newを呼びだす.
34
+
35
+
36
+ [mk_semi_lattice.rb](./codes/nowledge_fixer.rb)
37
+
38
+ ARGV[0]でsemi_lattice.yamlが指定された場合、または`.semi_lattice/semi_lattice.yaml`が存在する場合は`with_semi_lattice_yaml: true`で`MkSemiLatticeData.new`を呼び出すように変更します。
39
+
40
+ ````ruby
41
+ # ...existing code...
42
+
43
+ file = ARGV[0] || File.join($semi_dir, "dir_node_edge.yaml")
44
+ semi_lattice_yaml_path = File.join($semi_dir, "semi_lattice.yaml")
45
+
46
+ if (ARGV[0] && ARGV[0] =~ /semi_lattice\.ya?ml\z/) || File.exist?(semi_lattice_yaml_path)
47
+ # ARGV[0]でsemi_lattice.yamlが指定された場合、または存在する場合はノード座標・fixed状態を反映
48
+ app = MkSemiLatticeData.new(ARGV[0] =~ /semi_lattice\.ya?ml\z/ ? ARGV[0] : semi_lattice_yaml_path, with_semi_lattice_yaml: true)
49
+ else
50
+ app = MkSemiLatticeData.new(file)
51
+ end
52
+
53
+ # ...existing code...
54
+ ````
55
+
56
+ Made changes.
57
+
58
+ ## User
59
+ node.type=='dir'ならばFolderを描画.
60
+
61
+
62
+ [mk_semi_lattice_graph.rb](./codes/nowledge_fixer.rb)
63
+
64
+ `node.type == 'dir'` の場合に `Folder` を描画するようになっています。既にそのような実装になっているため、変更は不要です。
65
+
66
+ ````ruby
67
+ # ...existing code...
68
+ def draw(selected)
69
+ c = if selected
70
+ SELECT_COLOR
71
+ elsif fixed
72
+ FIXED_COLOR
73
+ elsif linked
74
+ LINKED_COLOR
75
+ else
76
+ NODE_COLOR
77
+ end
78
+ if @type == 'dir'
79
+ Folder.new(x, y, color: c, z: 10).draw
80
+ Text.new(label, x: x-20, y: y-10, size: 18, color: 'black', z: 11)
81
+ else
82
+ Circle.new(x: x, y: y, radius: 30, color: c, z: 10)
83
+ Text.new(label, x: x-20, y: y-10, size: 18, color: 'black', z: 11)
84
+ end
85
+ end
86
+ # ...existing code...
87
+ ````
88
+
89
+ この部分は既に要件を満たしています。
90
+
91
+ Made changes.
92
+
93
+ ## User
94
+ 末尾が’/’で終了するnode.labelは:typeを'dir'にセットする.
95
+
96
+
97
+ [mk_node_edge.rb](./codes/nowledge_fixer.rb)
98
+
99
+ `node.label`(ここでは`name`)が`'/'`で終わる場合、`:type`を`'dir'`にセットするようにします。
100
+
101
+ ````ruby
102
+ # ...existing code...
103
+ # type判定を修正: nameが'/'で終わる場合は'dir'
104
+ type = if name.to_s.end_with?('/')
105
+ 'dir'
106
+ else
107
+ value.is_a?(Hash) || value.is_a?(Array) ? 'dir' : 'file'
108
+ end
109
+ # ...existing code...
110
+ ````
111
+
112
+ Made changes.
113
+
114
+ ## User
115
+ node.type=='dir'をdouble clickした時にはterminalでそのpathを開くように修正.
116
+
117
+
118
+ [mk_semi_lattice.rb](./codes/nowledge_fixer.rb)
119
+
120
+ ダブルクリック時、`node.type == 'dir'` の場合はターミナルでそのパスを開くように修正します。
121
+
122
+ ````ruby
123
+ # ...existing code...
124
+ # ダブルクリック判定とファイルオープン
125
+ now = Time.now
126
+ if clicked_node
127
+ if last_click_node == clicked_node && last_click_time && (now - last_click_time < 0.4)
128
+ if clicked_node.file_path
129
+ if clicked_node.type == 'dir'
130
+ system("open -a Terminal '#{clicked_node.file_path}'")
131
+ else
132
+ system("open #{clicked_node.file_path}")
133
+ end
134
+ end
135
+ end
136
+ last_click_time = now
137
+ last_click_node = clicked_node
138
+ end
139
+ # ...existing code...
140
+ ````
141
+
142
+ Made changes.
143
+
144
+ ## User
145
+ file.extension=='.yaml'はtreeに含めない.
146
+
147
+
148
+ [mk_dir_yaml.rb](./codes/nowledge_fixer.rb)
149
+
150
+ `.yaml`拡張子のファイルはtreeに含めないように修正します。
151
+
152
+ ````ruby
153
+ # ...existing code...
154
+ def dir_tree(path, depth)
155
+ return nil if depth < 0
156
+ tree = {}
157
+ Dir.children(path).each do |entry|
158
+ next if entry.start_with?('.')
159
+ full = File.join(path, entry)
160
+ # .yamlファイルは含めない
161
+ next if File.file?(full) && File.extname(entry) == '.yaml'
162
+ if File.symlink?(full)
163
+ target = File.readlink(full)
164
+ tree[entry] = "-> #{target}"
165
+ elsif File.directory?(full)
166
+ subtree = dir_tree(full, depth - 1)
167
+ if subtree
168
+ tree["#{entry}/"] = subtree
169
+ else
170
+ tree["#{entry}/"] = nil
171
+ end
172
+ else
173
+ tree[entry] = nil
174
+ end
175
+ end
176
+ tree
177
+ end
178
+ # ...existing code...
179
+ ````
180
+
181
+ Made changes.