Class: VivlioStarter::CLI::UnifiedTermsManager
- Inherits:
-
Object
- Object
- VivlioStarter::CLI::UnifiedTermsManager
- Defined in:
- lib/vivlio_starter/cli/index/unified_terms_manager.rb
Constant Summary collapse
- UNIFIED_FILE =
'config/index_glossary_terms.yml'
Instance Method Summary collapse
-
#clear_cache! ⇒ Object
キャッシュをクリア.
-
#find_term(name) ⇒ Hash?
用語を名前で検索.
-
#follow_scanned_chapters(old_basename, new_basename) ⇒ Object
scanned_chapters を追随させる。 record_scanned_chapters! は「実在する章との積」を取るので、原稿ファイルが 移動済みなら旧章名はそこで自然に落ちる。新章名を渡すだけでよい。.
-
#glossary_term_names ⇒ Object
用語集対象の用語名.
-
#glossary_terms ⇒ Object
flags に g を含む用語(用語集対象).
-
#index_term_names ⇒ Object
索引対象の用語名.
-
#index_terms ⇒ Object
flags に i を含む用語(索引対象).
-
#initialize ⇒ UnifiedTermsManager
constructor
A new instance of UnifiedTermsManager.
-
#load_terms ⇒ Array<Hash>
全用語を読み込み.
-
#merge_terms!(new_terms, flags: 'i', source: 'auto_extracted') ⇒ Array<String>
用語をマージして保存 同名の用語が既存の場合は更新、なければ追加.
-
#record_scanned_chapters!(chapters) ⇒ Object
走査した章集合を和集合で記録する(R7)。 contents/ に実在する章だけ残し、改名・削除の残骸は落とす。 辞書ファイルが無いときは何もしない(空辞書を作ると「辞書なし」案内を壊すため).
-
#remove_flag!(term_name, remove_flag) ⇒ Object
flags から特定のフラグを除去(用語自体は残す) 例: flags 'ig' から 'i' を除去 → 'g' に変更.
-
#remove_term!(term_name) ⇒ Object
用語を削除.
-
#rename_chapter!(old_basename, new_basename) ⇒ Integer
章名の変更に辞書を追随させる(main: と scanned_chapters)。.
-
#rename_main_references(old_basename, new_basename) ⇒ Object
main: の章名を差し替える。単一指定は単一のまま戻す(著者が書いた形を保つ)。.
-
#scanned_chapters ⇒ Array<String>?
index:auto が走査した章集合(辞書トップレベル) キーが無い旧辞書・辞書なしでは nil(呼び出し側は判定をスキップする).
-
#term_names ⇒ Object
全用語名.
-
#update_definition!(term_name, definition) ⇒ Object
説明文を更新.
-
#update_flags!(term_name, new_flags) ⇒ Object
flags を更新.
-
#update_yomi!(yomi_changes) ⇒ Object
読みを更新.
Constructor Details
#initialize ⇒ UnifiedTermsManager
Returns a new instance of UnifiedTermsManager.
32 33 34 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 32 def initialize @cache = nil end |
Instance Method Details
#clear_cache! ⇒ Object
キャッシュをクリア
281 282 283 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 281 def clear_cache! @cache = nil end |
#find_term(name) ⇒ Hash?
用語を名前で検索
80 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 80 def find_term(name) = load_terms.find { it['term'] == name } |
#follow_scanned_chapters(old_basename, new_basename) ⇒ Object
scanned_chapters を追随させる。 record_scanned_chapters! は「実在する章との積」を取るので、原稿ファイルが 移動済みなら旧章名はそこで自然に落ちる。新章名を渡すだけでよい。
273 274 275 276 277 278 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 273 def follow_scanned_chapters(old_basename, new_basename) scanned = scanned_chapters return unless scanned&.include?(old_basename) record_scanned_chapters!([new_basename]) end |
#glossary_term_names ⇒ Object
用語集対象の用語名
75 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 75 def glossary_term_names = glossary_terms.map { it['term'] } |
#glossary_terms ⇒ Object
flags に g を含む用語(用語集対象)
66 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 66 def glossary_terms = load_terms.select { glossary_flag?(it['flags']) } |
#index_term_names ⇒ Object
索引対象の用語名
72 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 72 def index_term_names = index_terms.map { it['term'] } |
#index_terms ⇒ Object
flags に i を含む用語(索引対象)
63 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 63 def index_terms = load_terms.select { index_flag?(it['flags']) } |
#load_terms ⇒ Array<Hash>
全用語を読み込み
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 40 def load_terms return @cache if @cache unless File.exist?(UNIFIED_FILE) @cache = [] return @cache end begin data = YAML.load_file(UNIFIED_FILE, symbolize_names: false) terms = data['terms'] || [] # 後方互換: flags 未設定のエントリは用語集由来とみなし 'g' を付与 terms.each { it['flags'] ||= 'g' } @cache = terms rescue StandardError => e Common.log_warn("#{UNIFIED_FILE} の読み込みに失敗: #{e.}") @cache = [] end @cache end |
#merge_terms!(new_terms, flags: 'i', source: 'auto_extracted') ⇒ Array<String>
用語をマージして保存 同名の用語が既存の場合は更新、なければ追加
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 90 def merge_terms!(new_terms, flags: 'i', source: 'auto_extracted') return [] if new_terms.nil? || new_terms.empty? existing = load_terms.dup added_names = [] new_terms.each do |term| term_name = term['term'] || term[:term] next if term_name.nil? || term_name.empty? idx = existing.find_index { it['term'] == term_name } if idx # 既存用語を更新(flags をマージ、データを上書き) existing[idx] = merge_term_data(existing[idx], term, flags) else # 新規追加 existing << build_term_entry(term, flags, source) added_names << term_name end end save_terms!(existing) Common.log_success("#{added_names.size} 件の用語を追加しました") if added_names.any? added_names end |
#record_scanned_chapters!(chapters) ⇒ Object
走査した章集合を和集合で記録する(R7)。 contents/ に実在する章だけ残し、改名・削除の残骸は落とす。 辞書ファイルが無いときは何もしない(空辞書を作ると「辞書なし」案内を壊すため)
221 222 223 224 225 226 227 228 229 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 221 def record_scanned_chapters!(chapters) return unless File.exist?(UNIFIED_FILE) data = YAML.load_file(UNIFIED_FILE, symbolize_names: false) existing_files = Dir.glob(File.join(Common::CONTENTS_DIR, '*.md')).map { File.basename(it, '.md') } merged = ((data['scanned_chapters'] || []) | chapters.map { File.basename(it.to_s, '.md') }) & existing_files data['scanned_chapters'] = merged.sort File.write(UNIFIED_FILE, data.to_yaml, encoding: 'utf-8') end |
#remove_flag!(term_name, remove_flag) ⇒ Object
flags から特定のフラグを除去(用語自体は残す) 例: flags 'ig' から 'i' を除去 → 'g' に変更
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 132 def remove_flag!(term_name, remove_flag) existing = load_terms.dup term = existing.find { it['term'] == term_name } return unless term current = term['flags'] || '' new_flags = case remove_flag when 'i' then current.delete('i') when 'g' then current.delete('g') else current end if new_flags.empty? # フラグがなくなったら用語自体を削除 existing.reject! { it['term'] == term_name } else term['flags'] = new_flags end save_terms!(existing) end |
#remove_term!(term_name) ⇒ Object
用語を削除
118 119 120 121 122 123 124 125 126 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 118 def remove_term!(term_name) return if term_name.nil? || term_name.empty? existing = load_terms.dup original_size = existing.size existing.reject! { it['term'] == term_name } save_terms!(existing) if existing.size < original_size end |
#rename_chapter!(old_basename, new_basename) ⇒ Integer
章名の変更に辞書を追随させる(main: と scanned_chapters)。
main: は著者が下した判断=語彙の一次データなので、実在しない章を指していても 捨てられない。contexts はそもそも辞書に持たず(save_terms! を参照)、enrich が レビューのたびに本文から拾い直すので追随の対象にならない。 ここで書き換えるのは前者だけ。
241 242 243 244 245 246 247 248 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 241 def rename_chapter!(old_basename, new_basename) changed = rename_main_references(old_basename, new_basename) follow_scanned_chapters(old_basename, new_basename) return 0 if changed.zero? Common.log_info("索引辞書の主要参照を更新: #{old_basename} → #{new_basename}(#{changed} 語)") changed end |
#rename_main_references(old_basename, new_basename) ⇒ Object
main: の章名を差し替える。単一指定は単一のまま戻す(著者が書いた形を保つ)。
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 251 def rename_main_references(old_basename, new_basename) terms = load_terms changed = 0 terms.each do |term| next unless term['main'] before = Array(term['main']) after = before.map { it == old_basename ? new_basename : it } next if after == before term['main'] = term['main'].is_a?(Array) ? after : after.first changed += 1 end save_terms!(terms) if changed.positive? changed end |
#scanned_chapters ⇒ Array<String>?
index:auto が走査した章集合(辞書トップレベル) キーが無い旧辞書・辞書なしでは nil(呼び出し側は判定をスキップする)
208 209 210 211 212 213 214 215 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 208 def scanned_chapters return nil unless File.exist?(UNIFIED_FILE) data = YAML.load_file(UNIFIED_FILE, symbolize_names: false) data['scanned_chapters'] rescue StandardError nil end |
#term_names ⇒ Object
全用語名
69 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 69 def term_names = load_terms.map { it['term'] } |
#update_definition!(term_name, definition) ⇒ Object
説明文を更新
192 193 194 195 196 197 198 199 200 201 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 192 def update_definition!(term_name, definition) existing = load_terms.dup term = existing.find { it['term'] == term_name } return false unless term term['definition'] = definition term['updated_at'] = Time.now.strftime('%Y-%m-%d %H:%M:%S') save_terms!(existing) true end |
#update_flags!(term_name, new_flags) ⇒ Object
flags を更新
157 158 159 160 161 162 163 164 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 157 def update_flags!(term_name, new_flags) existing = load_terms.dup term = existing.find { it['term'] == term_name } return unless term term['flags'] = new_flags save_terms!(existing) end |
#update_yomi!(yomi_changes) ⇒ Object
読みを更新
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/vivlio_starter/cli/index/unified_terms_manager.rb', line 168 def update_yomi!(yomi_changes) return if yomi_changes.nil? || yomi_changes.empty? existing = load_terms.dup updated_count = 0 yomi_changes.each do |change| term = existing.find { it['term'] == change['term'] } next unless term next if term['yomi'] == change['yomi'] term['yomi'] = change['yomi'] updated_count += 1 end return unless updated_count.positive? save_terms!(existing) Common.log_info("#{updated_count} 件の読みを更新しました") end |