Class: Vivlio::Starter::CLI::ReviewMarkdownGenerator
- Inherits:
-
Object
- Object
- Vivlio::Starter::CLI::ReviewMarkdownGenerator
- Defined in:
- lib/vivlio/starter/cli/index/review_markdown_generator.rb
Constant Summary collapse
- REVIEW_FILE =
旧ファイル名との互換性のため、両方をチェック
'_index_glossary_review.md'- LEGACY_REVIEW_FILE =
'_index_review.md'
Instance Method Summary collapse
-
#cleanup! ⇒ Object
レビューファイルを削除.
-
#exists? ⇒ Boolean
レビューファイルが存在するか.
-
#generate!(data) ⇒ Object
レビュー用Markdownを生成.
-
#initialize ⇒ ReviewMarkdownGenerator
constructor
A new instance of ReviewMarkdownGenerator.
-
#parse_approved ⇒ Array<Hash>
後方互換性のため parse_approved も維持(索引用).
-
#parse_glossary_approved ⇒ Array<Hash>
用語集として承認された候補を抽出(, [ig], [gi] マーク) 説明文も抽出する.
-
#parse_glossary_rejected ⇒ Array<Hash>
用語集のみリジェクト(マーク)を抽出.
-
#parse_index_approved ⇒ Array<Hash>
索引として承認された候補を抽出(, [ig], [gi], [x] マーク).
-
#parse_index_rejected ⇒ Array<Hash>
索引のみリジェクト(マーク)を抽出.
-
#parse_rejected ⇒ Array<Hash>
リジェクト候補を抽出(High/Lowセクションから, [-ig]マークされたもの).
-
#parse_rejected_section_all ⇒ Array<Hash>
Rejectedセクションの全項目を抽出(フラグ不問) Section 4 に存在する全用語を返す([ ], [i], [g], [ig] 等すべて) apply 時に index_terms/glossary_terms からの除去と rejected への同期に使用.
-
#parse_terms_with_definitions(content) ⇒ Array<Hash>
用語と説明文をパース 出現箇所リストと説明文を区別して抽出.
-
#parse_unreject ⇒ Array<Hash>
Rejectedセクションで解除マークされた候補を抽出(リジェクト解除 + 直接登録) フラグに基づいて索引・用語集に直接登録する.
-
#parse_yomi_changes ⇒ Array<Hash>
Termsセクションで読みが変更された用語を抽出.
-
#review_file_path ⇒ String
実際のレビューファイルパスを取得.
Constructor Details
#initialize ⇒ ReviewMarkdownGenerator
Returns a new instance of ReviewMarkdownGenerator.
39 40 41 42 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 39 def initialize @content = nil @config = load_index_config end |
Instance Method Details
#cleanup! ⇒ Object
レビューファイルを削除
259 260 261 262 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 259 def cleanup! FileUtils.rm_f(REVIEW_FILE) FileUtils.rm_f(LEGACY_REVIEW_FILE) end |
#exists? ⇒ Boolean
レビューファイルが存在するか
60 61 62 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 60 def exists? File.exist?(REVIEW_FILE) || File.exist?(LEGACY_REVIEW_FILE) end |
#generate!(data) ⇒ Object
レビュー用Markdownを生成
50 51 52 53 54 55 56 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 50 def generate!(data) content = build_markdown(data) File.write(REVIEW_FILE, content, encoding: 'utf-8') Common.log_success("レビュー用ファイルを生成しました: #{REVIEW_FILE}") Common.log_info('ファイルを開いて [ ] を [x] または [r] に変更してください') Common.log_info('完了したら: vs index:apply') end |
#parse_approved ⇒ Array<Hash>
後方互換性のため parse_approved も維持(索引用)
117 118 119 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 117 def parse_approved parse_index_approved end |
#parse_glossary_approved ⇒ Array<Hash>
用語集として承認された候補を抽出(, [ig], [gi] マーク)説明文も抽出する
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 93 def parse_glossary_approved return [] unless exists? content = File.read(review_file_path, encoding: 'utf-8') approved = [] # [g], [ig], [gi] を用語集として抽出 parse_terms_with_definitions(content).each do |entry| flag = entry[:flag] next unless flag.match?(/^(?:g|ig|gi)$/) approved << { 'term' => entry[:term], 'yomi' => entry[:yomi], 'definition' => entry[:definition], 'contexts' => entry[:contexts] } end approved end |
#parse_glossary_rejected ⇒ Array<Hash>
用語集のみリジェクト(マーク)を抽出
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 169 def parse_glossary_rejected return [] unless exists? content = File.read(review_file_path, encoding: 'utf-8') rejected = [] rejected_section_start = content.index('## 4. 除外済みリスト') search_content = rejected_section_start ? content[0...rejected_section_start] : content search_content.scan(/^- \[-g\](?: `(?:NEW!|Today)`)? \*\*(.+?)\*\* \(([^)]+)\)/) do |term, yomi| rejected << { 'term' => term, 'yomi' => yomi, 'kind' => 'glossary' } end rejected end |
#parse_index_approved ⇒ Array<Hash>
索引として承認された候補を抽出(, [ig], [gi], [x] マーク)
75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 75 def parse_index_approved return [] unless exists? content = File.read(review_file_path, encoding: 'utf-8') approved = [] # [i], [ig], [gi], [x] を索引として抽出 # 形式: - [i] `NEW!` **用語** (読み) - スコア: 123.5 content.scan(/^- \[(?:i|ig|gi|x)\](?: `(?:NEW!|Today)`)? \*\*(.+?)\*\* \(([^)]+)\)/) do |term, yomi| approved << { 'term' => term, 'yomi' => yomi } end approved end |
#parse_index_rejected ⇒ Array<Hash>
索引のみリジェクト(マーク)を抽出
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 151 def parse_index_rejected return [] unless exists? content = File.read(review_file_path, encoding: 'utf-8') rejected = [] rejected_section_start = content.index('## 4. 除外済みリスト') search_content = rejected_section_start ? content[0...rejected_section_start] : content search_content.scan(/^- \[-i\](?: `(?:NEW!|Today)`)? \*\*(.+?)\*\* \(([^)]+)\)/) do |term, yomi| rejected << { 'term' => term, 'yomi' => yomi, 'kind' => 'index' } end rejected end |
#parse_rejected ⇒ Array<Hash>
リジェクト候補を抽出(High/Lowセクションから, [-ig]マークされたもの)
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 123 def parse_rejected return [] unless exists? content = File.read(review_file_path, encoding: 'utf-8') rejected = [] # Rejectedセクション以外から [r] マークを抽出 # Rejectedセクションの開始位置を特定 rejected_section_start = content.index('## 4. 除外済みリスト') search_content = if rejected_section_start content[0...rejected_section_start] else content end # [r], [-ig], [-gi] を両方リジェクトとして抽出 search_content.scan(/^- \[(?:r|-ig|-gi)\](?: `(?:NEW!|Today)`)? \*\*(.+?)\*\* \(([^)]+)\)(?: - スコア: ([\d.]+))?/) do |term, yomi, score| entry = { 'term' => term, 'yomi' => yomi, 'kind' => 'both' } entry['score'] = score.to_f if score rejected << entry end rejected end |
#parse_rejected_section_all ⇒ Array<Hash>
Rejectedセクションの全項目を抽出(フラグ不問)Section 4 に存在する全用語を返す([ ], [i], [g], [ig] 等すべて)apply 時に index_terms/glossary_terms からの除去と rejected への同期に使用
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 213 def parse_rejected_section_all return [] unless exists? content = File.read(review_file_path, encoding: 'utf-8') items = [] rejected_section_start = content.index('## 4. 除外済みリスト') return [] unless rejected_section_start rejected_content = content[rejected_section_start..] # フラグ部分を含めて全項目を抽出 # [ ], [i], [g], [ig], [gi], [x], [r] 等すべてのフラグを対象 rejected_content.scan(/^- \[([^\]]*)\](?: `(?:NEW!|Today)`)? \*\*(.+?)\*\* \(([^)]+)\)/) do |flag, term, yomi| items << { 'term' => term, 'yomi' => yomi, 'flag' => flag.strip } end items end |
#parse_terms_with_definitions(content) ⇒ Array<Hash>
用語と説明文をパース出現箇所リストと説明文を区別して抽出
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 268 def parse_terms_with_definitions(content) results = [] lines = content.lines i = 0 while i < lines.size line = lines[i] # 用語行を検出: - [flag] **用語** (読み) - スコア: 123.5 if line =~ /^- \[([^\]]+)\](?: `(?:NEW!|Today)`)? \*\*(.+?)\*\* \(([^)]+)\)/ flag = Regexp.last_match(1) term = Regexp.last_match(2) yomi = Regexp.last_match(3) i += 1 contexts = [] definition_lines = [] in_definition = false # 次の用語行まで走査 while i < lines.size && lines[i] !~ /^- \[/ current_line = lines[i] # 出現箇所行: " - chapter: context" if current_line =~ /^ - ([^:]+): (.+)/ chapter = Regexp.last_match(1) context_text = Regexp.last_match(2) contexts << { 'chapter' => chapter, 'context' => context_text } i += 1 next end # 空行で説明文開始を判定 if current_line.strip.empty? in_definition = true i += 1 next end # インデントされた行は説明文 definition_lines << Regexp.last_match(1) if in_definition && current_line =~ /^ (.+)/ i += 1 end results << { flag: flag, term: term, yomi: yomi, contexts: contexts, definition: definition_lines.join("\n").strip } else i += 1 end end results end |
#parse_unreject ⇒ Array<Hash>
Rejectedセクションで解除マークされた候補を抽出(リジェクト解除 + 直接登録)フラグに基づいて索引・用語集に直接登録する
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 188 def parse_unreject return [] unless exists? content = File.read(review_file_path, encoding: 'utf-8') unreject = [] # Rejectedセクションを特定 rejected_section_start = content.index('## 4. 除外済みリスト') return [] unless rejected_section_start rejected_content = content[rejected_section_start..] # Rejectedセクション内で [i], [g], [ig] マークされたものを抽出 # フラグも保持し、索引・用語集への直接登録に使用する rejected_content.scan(/^- \[(i|g|ig|gi|x)\](?: `(?:NEW!|Today)`)? \*\*(.+?)\*\* \(([^)]+)\)/) do |flag, term, yomi| unreject << { 'term' => term, 'yomi' => yomi, 'flag' => flag } end unreject end |
#parse_yomi_changes ⇒ Array<Hash>
Termsセクションで読みが変更された用語を抽出
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 235 def parse_yomi_changes return [] unless exists? content = File.read(review_file_path, encoding: 'utf-8') changes = [] # Termsセクションを特定 terms_section_start = content.index('## 1. 登録済み用語の確認') high_section_start = content.index('## 2. 推奨候補') return [] unless terms_section_start terms_end = high_section_start || content.length terms_content = content[terms_section_start...terms_end] # [i], [g], [ig], [x] マークされた用語の読みを抽出 terms_content.scan(/^- \[(?:i|g|ig|gi|x)\](?: `(?:NEW!|Today)`)? \*\*(.+?)\*\* \(([^)]+)\)/) do |term, yomi| changes << { 'term' => term, 'yomi' => yomi } end changes end |
#review_file_path ⇒ String
実際のレビューファイルパスを取得
66 67 68 69 70 71 |
# File 'lib/vivlio/starter/cli/index/review_markdown_generator.rb', line 66 def review_file_path return REVIEW_FILE if File.exist?(REVIEW_FILE) return LEGACY_REVIEW_FILE if File.exist?(LEGACY_REVIEW_FILE) REVIEW_FILE end |