wp2txt 1.1.3 → 2.1.0

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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +12 -0
  3. data/.github/workflows/ci.yml +13 -13
  4. data/.gitignore +14 -0
  5. data/CHANGELOG.md +284 -0
  6. data/DEVELOPMENT.md +415 -0
  7. data/DEVELOPMENT_ja.md +415 -0
  8. data/Dockerfile +19 -10
  9. data/Gemfile +2 -8
  10. data/README.md +259 -123
  11. data/README_ja.md +375 -0
  12. data/Rakefile +4 -0
  13. data/bin/wp2txt +863 -161
  14. data/lib/wp2txt/article.rb +98 -13
  15. data/lib/wp2txt/bz2_validator.rb +239 -0
  16. data/lib/wp2txt/category_cache.rb +313 -0
  17. data/lib/wp2txt/cli.rb +319 -0
  18. data/lib/wp2txt/cli_ui.rb +428 -0
  19. data/lib/wp2txt/config.rb +158 -0
  20. data/lib/wp2txt/constants.rb +134 -0
  21. data/lib/wp2txt/data/html_entities.json +2135 -0
  22. data/lib/wp2txt/data/language_metadata.json +4769 -0
  23. data/lib/wp2txt/data/language_tiers.json +59 -0
  24. data/lib/wp2txt/data/mediawiki_aliases.json +12366 -0
  25. data/lib/wp2txt/data/template_aliases.json +193 -0
  26. data/lib/wp2txt/data/wikipedia_entities.json +12 -0
  27. data/lib/wp2txt/extractor.rb +545 -0
  28. data/lib/wp2txt/file_utils.rb +91 -0
  29. data/lib/wp2txt/formatter.rb +352 -0
  30. data/lib/wp2txt/global_data_cache.rb +353 -0
  31. data/lib/wp2txt/index_cache.rb +258 -0
  32. data/lib/wp2txt/magic_words.rb +353 -0
  33. data/lib/wp2txt/memory_monitor.rb +236 -0
  34. data/lib/wp2txt/multistream.rb +1383 -0
  35. data/lib/wp2txt/output_writer.rb +182 -0
  36. data/lib/wp2txt/parser_functions.rb +606 -0
  37. data/lib/wp2txt/ractor_worker.rb +215 -0
  38. data/lib/wp2txt/regex.rb +396 -12
  39. data/lib/wp2txt/section_extractor.rb +354 -0
  40. data/lib/wp2txt/stream_processor.rb +271 -0
  41. data/lib/wp2txt/template_expander.rb +830 -0
  42. data/lib/wp2txt/text_processing.rb +337 -0
  43. data/lib/wp2txt/utils.rb +629 -270
  44. data/lib/wp2txt/version.rb +1 -1
  45. data/lib/wp2txt.rb +53 -26
  46. data/scripts/benchmark_regex.rb +161 -0
  47. data/scripts/fetch_html_entities.rb +94 -0
  48. data/scripts/fetch_language_metadata.rb +180 -0
  49. data/scripts/fetch_mediawiki_data.rb +334 -0
  50. data/scripts/fetch_template_data.rb +186 -0
  51. data/scripts/profile_memory.rb +139 -0
  52. data/spec/article_spec.rb +402 -0
  53. data/spec/auto_download_spec.rb +314 -0
  54. data/spec/bz2_validator_spec.rb +193 -0
  55. data/spec/category_cache_spec.rb +226 -0
  56. data/spec/category_fetcher_spec.rb +504 -0
  57. data/spec/cleanup_spec.rb +197 -0
  58. data/spec/cli_options_spec.rb +678 -0
  59. data/spec/cli_spec.rb +876 -0
  60. data/spec/config_spec.rb +194 -0
  61. data/spec/constants_spec.rb +138 -0
  62. data/spec/file_utils_spec.rb +170 -0
  63. data/spec/fixtures/samples.rb +181 -0
  64. data/spec/formatter_sections_spec.rb +382 -0
  65. data/spec/global_data_cache_spec.rb +186 -0
  66. data/spec/index_cache_spec.rb +210 -0
  67. data/spec/integration_spec.rb +543 -0
  68. data/spec/magic_words_spec.rb +261 -0
  69. data/spec/markers_spec.rb +476 -0
  70. data/spec/memory_monitor_spec.rb +192 -0
  71. data/spec/multistream_spec.rb +690 -0
  72. data/spec/output_writer_spec.rb +400 -0
  73. data/spec/parser_functions_spec.rb +455 -0
  74. data/spec/ractor_worker_spec.rb +197 -0
  75. data/spec/regex_spec.rb +281 -0
  76. data/spec/section_extractor_spec.rb +397 -0
  77. data/spec/spec_helper.rb +63 -0
  78. data/spec/stream_processor_spec.rb +579 -0
  79. data/spec/template_data_spec.rb +246 -0
  80. data/spec/template_expander_spec.rb +472 -0
  81. data/spec/template_processing_spec.rb +217 -0
  82. data/spec/text_processing_spec.rb +312 -0
  83. data/spec/utils_spec.rb +195 -16
  84. data/spec/wp2txt_spec.rb +510 -0
  85. data/wp2txt.gemspec +5 -3
  86. metadata +146 -18
  87. data/.rubocop.yml +0 -80
  88. data/data/output_samples/testdata_en.txt +0 -23002
  89. data/data/output_samples/testdata_en_category.txt +0 -132
  90. data/data/output_samples/testdata_en_summary.txt +0 -1376
  91. data/data/output_samples/testdata_ja.txt +0 -22774
  92. data/data/output_samples/testdata_ja_category.txt +0 -206
  93. data/data/output_samples/testdata_ja_summary.txt +0 -1560
  94. data/data/testdata_en.bz2 +0 -0
  95. data/data/testdata_ja.bz2 +0 -0
  96. data/image/screenshot.png +0 -0
data/DEVELOPMENT_ja.md ADDED
@@ -0,0 +1,415 @@
1
+ # WP2TXT 開発ガイド
2
+
3
+ このドキュメントはWP2TXTの開発者向けガイダンスを提供します。ユーザードキュメントは[README_ja.md](README_ja.md)を参照してください。
4
+
5
+ [English](DEVELOPMENT.md) | 日本語
6
+
7
+ ## クイックスタート
8
+
9
+ ```bash
10
+ # 依存関係をインストール
11
+ bundle install
12
+
13
+ # テストを実行
14
+ bundle exec rspec
15
+
16
+ # カバレッジ付きでテストを実行
17
+ bundle exec rspec # カバレッジレポートは coverage/index.html
18
+ ```
19
+
20
+ ## アーキテクチャ概要
21
+
22
+ ### 処理パイプライン
23
+
24
+ WP2TXTはWikipediaダンプを処理するためにストリーミングアーキテクチャを使用します:
25
+
26
+ ```
27
+ 入力 (bz2/xml) → StreamProcessor → Article Parser → OutputWriter → 出力ファイル
28
+ ```
29
+
30
+ 1. **StreamProcessor** (`lib/wp2txt.rb`): bz2を解凍しXMLページをストリーミング
31
+ 2. **Article** (`lib/wp2txt/article.rb`): MediaWikiテキストを型付き要素にパース
32
+ 3. **Utils** (`lib/wp2txt/utils.rb`): テキストフォーマットとクリーンアップ関数を提供
33
+ 4. **OutputWriter** (`lib/wp2txt.rb`): テキストまたはJSON形式で出力を書き込み
34
+
35
+ ### コアクラス
36
+
37
+ | クラス | ファイル | 目的 |
38
+ |--------|----------|------|
39
+ | `StreamProcessor` | `lib/wp2txt/stream_processor.rb` | 適応的バッファリングで圧縮ダンプからページをストリーミング |
40
+ | `Article` | `lib/wp2txt/article.rb` | MediaWikiマークアップをパース |
41
+ | `OutputWriter` | `lib/wp2txt.rb` | 出力ファイルローテーションを管理 |
42
+ | `DumpManager` | `lib/wp2txt/multistream.rb` | ダンプをダウンロード・キャッシュ |
43
+ | `MultistreamIndex` | `lib/wp2txt/multistream.rb` | ランダムアクセス用に記事をインデックス化 |
44
+ | `MultistreamReader` | `lib/wp2txt/multistream.rb` | 記事を抽出(並列抽出対応) |
45
+ | `CategoryFetcher` | `lib/wp2txt/multistream.rb` | Wikipedia APIからカテゴリメンバーを取得 |
46
+ | `MemoryMonitor` | `lib/wp2txt/memory_monitor.rb` | クロスプラットフォームメモリ監視 |
47
+ | `Bz2Validator` | `lib/wp2txt/bz2_validator.rb` | bz2ファイルの整合性を検証 |
48
+ | `CLI` | `lib/wp2txt/cli.rb` | コマンドラインオプションのパース |
49
+
50
+ ### キャッシュクラス
51
+
52
+ | クラス | ファイル | 目的 |
53
+ |--------|----------|------|
54
+ | `GlobalDataCache` | `lib/wp2txt/global_data_cache.rb` | パース済みJSONデータファイルのSQLiteキャッシュ |
55
+ | `CategoryCache` | `lib/wp2txt/category_cache.rb` | Wikipediaカテゴリ階層のSQLiteキャッシュ |
56
+ | `IndexCache` | `lib/wp2txt/index_cache.rb` | マルチストリームインデックスエントリのSQLiteキャッシュ |
57
+
58
+ ### 要素タイプ
59
+
60
+ `Article`クラスはMediaWikiテキストを型付き要素にパースします:
61
+
62
+ | タイプ | 説明 |
63
+ |--------|------|
64
+ | `:mw_heading` | セクション見出し (`== タイトル ==`) |
65
+ | `:mw_paragraph` | 通常のテキスト段落 |
66
+ | `:mw_table` | Wikiテーブル (`{| ... |}`) |
67
+ | `:mw_quote` | ブロッククォート |
68
+ | `:mw_pre` | 整形済みテキスト |
69
+ | `:mw_unordered` | 順序なしリスト項目 |
70
+ | `:mw_ordered` | 順序付きリスト項目 |
71
+ | `:mw_definition` | 定義リスト項目 |
72
+ | `:mw_link` | 単一行リンク |
73
+ | `:mw_ml_link` | 複数行リンク |
74
+ | `:mw_redirect` | リダイレクトページ |
75
+ | `:mw_template` | テンプレート |
76
+ | `:mw_isolated_tag` | HTMLタグ |
77
+
78
+ ### マーカーシステム
79
+
80
+ コンテンツタイプマーカーは特殊コンテンツ(math、codeなど)をプレースホルダーに置き換えます:
81
+
82
+ ```ruby
83
+ # utils.rb内
84
+ MARKER_TYPES = %i[math code chem table score timeline graph ipa].freeze
85
+
86
+ # 処理フロー:
87
+ # 1. コンテンツ検出 → プレースホルダーに置換 («« MATH »»)
88
+ # 2. テキスト処理続行(プレースホルダーはクリーンアップから保護)
89
+ # 3. finalize_markers() がプレースホルダーを [MARKER] 形式に変換
90
+ ```
91
+
92
+ ### テンプレート展開
93
+
94
+ `TemplateExpander`クラス(`lib/wp2txt/template_expander.rb`)は一般的なWikipediaテンプレートを可読テキストに展開します:
95
+
96
+ | テンプレートタイプ | 例 | 出力 |
97
+ |--------------------|-----|------|
98
+ | 生年月日/没年月日 | `{{birth date|1990|5|15}}` | "May 15, 1990" |
99
+ | 単位変換 | `{{convert|100|km|mi}}` | "100 km (62 mi)" |
100
+ | 座標 | `{{coord|35|41|N|139|41|E}}` | "35°41′N 139°41′E" |
101
+ | 言語タグ | `{{lang|ja|日本語}}` | "日本語" |
102
+ | 仮名 | `{{nihongo|Tokyo|東京|Tōkyō}}` | "Tokyo (東京, Tōkyō)" |
103
+
104
+ テンプレート展開はデフォルトで有効です。`--no-expand-templates`または`expand_templates: false`で無効化できます。
105
+
106
+ ### マジックワード展開
107
+
108
+ `MagicWordExpander`クラス(`lib/wp2txt/magic_words.rb`)はMediaWikiマジックワードを実際の値に展開します:
109
+
110
+ | カテゴリ | マジックワード | 例 |
111
+ |----------|----------------|-----|
112
+ | ページ文脈 | `PAGENAME`, `FULLPAGENAME`, `BASEPAGENAME`, `ROOTPAGENAME`, `SUBPAGENAME`, `NAMESPACE`, `TALKPAGENAME` | `{{PAGENAME}}` → "記事タイトル" |
113
+ | 日時 | `CURRENTYEAR`, `CURRENTMONTH`, `CURRENTDAY`, `CURRENTDAYNAME`, `CURRENTTIME`, `CURRENTTIMESTAMP` | `{{CURRENTYEAR}}` → "2024" |
114
+ | 文字列関数 | `lc`, `uc`, `lcfirst`, `ucfirst`, `urlencode`, `anchorencode`, `padleft`, `padright` | `{{uc:hello}}` → "HELLO" |
115
+ | パーサー関数 | `#titleparts` | `{{#titleparts:A/B/C\|2}}` → "A/B" |
116
+
117
+ マジックワードは`format_wiki()`パイプラインの早い段階で、configにtitleが指定されている場合に展開されます:
118
+
119
+ ```ruby
120
+ result = format_wiki(text, title: "記事名", dump_date: Time.now)
121
+ ```
122
+
123
+ ## キャッシングインフラストラクチャ
124
+
125
+ WP2TXTはSQLiteベースのキャッシュを使用して、繰り返し実行時のパフォーマンスを向上させています。すべてのキャッシュは `~/.wp2txt/cache/` に保存されます。
126
+
127
+ ### GlobalDataCache
128
+
129
+ パース済みJSONデータファイル(テンプレート、MediaWikiエイリアス、HTMLエンティティ)をキャッシュし、パースのオーバーヘッドを削減:
130
+
131
+ ```ruby
132
+ # 自動 - データ読み込みメソッドは透過的にキャッシュを使用
133
+ data = Wp2txt.load_mediawiki_data # 有効であればキャッシュを使用
134
+
135
+ # 手動キャッシュ操作
136
+ Wp2txt::GlobalDataCache.clear! # キャッシュをすべてクリア
137
+ Wp2txt::GlobalDataCache.stats # キャッシュ統計を取得
138
+ ```
139
+
140
+ キャッシュ検証:ソースファイルの変更時刻とサイズをチェックします。ソースファイルが変更されると自動的にキャッシュは無効化されます。
141
+
142
+ ### CategoryCache
143
+
144
+ Wikipedia APIからのカテゴリ階層をキャッシュし、カテゴリベースの記事抽出を高速化:
145
+
146
+ ```ruby
147
+ cache = Wp2txt::CategoryCache.new("en", cache_dir: "/path/to/cache")
148
+
149
+ # カテゴリデータを保存
150
+ cache.save("カテゴリ名", ["記事1", "記事2"], ["サブカテゴリ1"])
151
+
152
+ # カテゴリデータを取得
153
+ data = cache.get("カテゴリ名") # { pages: [...], subcats: [...] }
154
+
155
+ # カテゴリツリー内のすべてのページを取得
156
+ pages = cache.get_all_pages("ルートカテゴリ", max_depth: 2)
157
+
158
+ # 統計とメンテナンス
159
+ cache.stats # キャッシュ統計
160
+ cache.cleanup_expired! # 古いエントリを削除
161
+ cache.clear! # すべてクリア
162
+ ```
163
+
164
+ ### IndexCache
165
+
166
+ パース済みマルチストリームインデックスエントリをキャッシュし、記事の高速検索を実現:
167
+
168
+ ```ruby
169
+ cache = Wp2txt::IndexCache.new("/path/to/index.txt", cache_dir: "/path/to/cache")
170
+
171
+ # キャッシュの有効性を確認
172
+ cache.valid? # キャッシュが存在しソースファイルと一致する場合 true
173
+
174
+ # 保存/読み込み操作(MultistreamIndexで内部的に使用)
175
+ cache.save(entries_by_title, stream_offsets)
176
+ data = cache.load # { entries_by_title: {}, entries_by_id: {}, stream_offsets: [] }
177
+
178
+ # バッチ検索
179
+ results = cache.find_by_titles(["記事1", "記事2"])
180
+ ```
181
+
182
+ ### キャッシュの場所
183
+
184
+ すべてのキャッシュは `~/.wp2txt/cache/` に保存されます:
185
+
186
+ ```
187
+ ~/.wp2txt/cache/
188
+ ├── global_data.sqlite3 # GlobalDataCache
189
+ ├── categories_en.sqlite3 # CategoryCache(英語)
190
+ ├── categories_ja.sqlite3 # CategoryCache(日本語)
191
+ └── enwiki_*_index.sqlite3 # IndexCache(ダンプファイルごと)
192
+ ```
193
+
194
+ ## テストシステム
195
+
196
+ ### テスト構造
197
+
198
+ ```
199
+ spec/
200
+ ├── spec_helper.rb # RSpec設定
201
+ ├── article_spec.rb # 記事パーステスト
202
+ ├── utils_spec.rb # テキスト処理テスト
203
+ ├── markers_spec.rb # マーカー機能テスト
204
+ ├── auto_download_spec.rb # CLIとダウンロードテスト
205
+ ├── multilingual_spec.rb # 言語固有テスト
206
+ ├── streaming_spec.rb # ストリーミングアーキテクチャテスト
207
+ └── testdata/ # 静的テストデータ
208
+ ```
209
+
210
+ ### テストの実行
211
+
212
+ ```bash
213
+ # 全テストを実行
214
+ bundle exec rspec
215
+
216
+ # 特定のテストファイルを実行
217
+ bundle exec rspec spec/utils_spec.rb
218
+
219
+ # ドキュメント形式で実行
220
+ bundle exec rspec --format documentation
221
+
222
+ # 行番号で特定のテストを実行
223
+ bundle exec rspec spec/utils_spec.rb:42
224
+ ```
225
+
226
+ ## マルチストリームサポート
227
+
228
+ WP2TXTは効率的な記事抽出のためにWikipediaのマルチストリーム形式をサポートしています。
229
+
230
+ ### マルチストリームの仕組み
231
+
232
+ 1. **インデックスファイル** (`-multistream-index.txt.bz2`): 記事タイトルをバイトオフセットにマッピング
233
+ 2. **マルチストリームファイル** (`-multistream.xml.bz2`): 連結されたbz2ストリーム
234
+
235
+ ### 並列抽出
236
+
237
+ `MultistreamReader`はパフォーマンス向上のための並列記事抽出をサポートしています:
238
+
239
+ ```ruby
240
+ reader = MultistreamReader.new(multistream_path, index_path)
241
+
242
+ # 複数の記事を並列で抽出(デフォルト4プロセス)
243
+ results = reader.extract_articles_parallel(["東京", "京都", "大阪"], num_processes: 4)
244
+
245
+ # 並列処理でイテレート
246
+ reader.each_article_parallel(entries, num_processes: 4) do |page|
247
+ process(page)
248
+ end
249
+ ```
250
+
251
+ 記事はストリームオフセットでグループ化され、bz2解凍のオーバーヘッドを最小化します。
252
+
253
+ ### 部分ダウンロード
254
+
255
+ 特定の記事抽出では、WP2TXTは必要なデータのみをダウンロードします:
256
+
257
+ ```ruby
258
+ # 最初のNストリームのみダウンロード
259
+ manager.download_multistream(max_streams: 10)
260
+
261
+ # 必要なバイト範囲のみダウンロード
262
+ download_file_range(url, path, start_byte, end_byte)
263
+ ```
264
+
265
+ ### 差分ダウンロード
266
+
267
+ 部分ダンプが存在する場合、`download_multistream_full`はダウンロードを再開できます:
268
+
269
+ ```ruby
270
+ manager = DumpManager.new("ja")
271
+
272
+ # 既存の部分ダンプを確認
273
+ partial = manager.find_any_partial_cache
274
+ # => { path: "...", dump_date: "20260101", stream_count: 100, size: 1000000, mtime: ... }
275
+
276
+ # 差分ダウンロードが可能か確認
277
+ resume_info = manager.can_resume_from_partial?(partial)
278
+ # => { possible: true, current_streams: 100, total_streams: 5000, current_size: 1000000 }
279
+ # => { possible: false, reason: :date_mismatch, partial_date: "20250101", latest_date: "20260101" }
280
+
281
+ # 差分ダウンロードサポート付きでフルダンプをダウンロード(対話式プロンプト)
282
+ path = manager.download_multistream_full(interactive: true)
283
+
284
+ # 非対話モード(ユーザープロンプトをスキップ、必要に応じて常に新規ダウンロード)
285
+ path = manager.download_multistream_full(interactive: false)
286
+ ```
287
+
288
+ 差分ダウンロードのユーザープロンプト:
289
+
290
+ 1. **同一日付の部分ダンプが存在:**
291
+ - `[Y]` ダウンロードを再開(残りのデータのみダウンロード)
292
+ - `[n]` 既存の部分ダンプをそのまま使用
293
+ - `[f]` 新規フルダンプをダウンロード
294
+
295
+ 2. **古い部分ダンプが存在:**
296
+ - `[D]` 古い部分を削除して最新をダウンロード(推奨)
297
+ - `[k]` 古い部分を保持、最新を別途ダウンロード
298
+ - `[u]` 古い部分をそのまま使用(内容が古い可能性あり)
299
+
300
+ ### 記事抽出フロー
301
+
302
+ ```
303
+ 1. インデックスファイルをダウンロード(英語版で約500MB)
304
+ 2. インデックスをハッシュにロード(O(1)ルックアップ)
305
+ 3. 記事オフセットを検索
306
+ 4. ストリームオフセットでグループ化
307
+ 5. 必要なストリームのみダウンロード
308
+ 6. 特定の記事を抽出
309
+ ```
310
+
311
+ ## メモリ管理
312
+
313
+ WP2TXTには大規模ダンプ処理のための適応型メモリ管理が含まれています:
314
+
315
+ ### MemoryMonitor
316
+
317
+ `lib/wp2txt/memory_monitor.rb`でのクロスプラットフォームメモリ監視:
318
+
319
+ ```ruby
320
+ # 現在のメモリ使用量を確認
321
+ stats = Wp2txt::MemoryMonitor.memory_stats
322
+ # => { current: 256000000, available: 8000000000, ... }
323
+
324
+ # 利用可能メモリに基づく最適バッファサイズを取得
325
+ buffer_size = Wp2txt::MemoryMonitor.optimal_buffer_size
326
+ # => 10485760 (10 MB)
327
+
328
+ # メモリが少ない場合GCをトリガー
329
+ Wp2txt::MemoryMonitor.gc_if_needed
330
+ ```
331
+
332
+ ### StreamProcessorの適応的バッファリング
333
+
334
+ `StreamProcessor`はバッファサイズを動的に調整します:
335
+
336
+ ```ruby
337
+ processor = Wp2txt::StreamProcessor.new(input_path, adaptive_buffer: true)
338
+ processor.each_page { |title, text| ... }
339
+
340
+ # 処理統計を監視
341
+ processor.stats
342
+ # => { pages_processed: 1000, bytes_read: 50000000, buffer_size: 10485760, ... }
343
+ ```
344
+
345
+ ## bz2検証
346
+
347
+ `Bz2Validator`モジュールは処理前にbz2ファイルを検証します:
348
+
349
+ ```ruby
350
+ # 完全検証(ヘッダー + 解凍テスト)
351
+ result = Wp2txt::Bz2Validator.validate("/path/to/file.bz2")
352
+ result.valid? # => true/false
353
+ result.error_type # => :invalid_magic, :too_small など
354
+ result.message # => "Invalid bz2 header..."
355
+
356
+ # クイック検証(ヘッダーのみ)
357
+ result = Wp2txt::Bz2Validator.validate_quick("/path/to/file.bz2")
358
+
359
+ # ファイル情報を取得
360
+ info = Wp2txt::Bz2Validator.file_info("/path/to/file.bz2")
361
+ # => { path: "...", size: 1000000, valid_header: true, version: "h", block_size: 9, ... }
362
+ ```
363
+
364
+ ## 新機能の追加
365
+
366
+ ### 新しいマーカータイプの追加
367
+
368
+ 1. `lib/wp2txt/utils.rb`の`MARKER_TYPES`に追加
369
+ 2. `apply_markers()`に検出パターンを追加
370
+ 3. `spec/markers_spec.rb`にテストを追加
371
+
372
+ ### 新しいCLIオプションの追加
373
+
374
+ 1. `lib/wp2txt/cli.rb`にオプション定義を追加
375
+ 2. `validate_options!()`にバリデーションを追加
376
+ 3. `bin/wp2txt`でオプションを処理
377
+ 4. `spec/auto_download_spec.rb`にテストを追加
378
+ 5. README.mdを更新
379
+
380
+ ### 言語サポートの追加
381
+
382
+ 1. カテゴリキーワード: `data/language_categories.json`
383
+ 2. リダイレクトキーワード: `data/language_redirects.json`
384
+ 3. スクリプト: `scripts/generate_language_data.rb`
385
+
386
+ ## コードスタイル
387
+
388
+ - Ruby 2.6+互換性
389
+ - フローズンストリングリテラル (`# frozen_string_literal: true`)
390
+ - RuboCop設定は`.rubocop.yml`
391
+ - 全体でUTF-8エンコーディング
392
+
393
+ ## Docker
394
+
395
+ Dockerイメージのビルドとプッシュ:
396
+
397
+ ```bash
398
+ rake push # マルチアーキテクチャでビルドしDocker Hubにプッシュ
399
+ ```
400
+
401
+ ## リリースプロセス
402
+
403
+ 1. `lib/wp2txt/version.rb`のバージョンを更新
404
+ 2. CHANGELOG.mdを更新
405
+ 3. フルテストスイートを実行: `bundle exec rspec`
406
+ 4. gemをビルド: `gem build wp2txt.gemspec`
407
+ 5. RubyGemsにプッシュ: `gem push wp2txt-*.gem`
408
+ 6. Dockerイメージをプッシュ: `rake push`
409
+ 7. GitHubリリースを作成
410
+
411
+ ## 便利なリンク
412
+
413
+ - [MediaWikiマークアップリファレンス](https://www.mediawiki.org/wiki/Help:Formatting)
414
+ - [Wikipediaダンプダウンロード](https://dumps.wikimedia.org/)
415
+ - [マルチストリーム形式](https://meta.wikimedia.org/wiki/Data_dumps/FAQ#Why_are_there_multiple_files_for_a_single_dump?)
data/Dockerfile CHANGED
@@ -1,20 +1,29 @@
1
- FROM ruby:3.1.3-alpine3.17
1
+ FROM ruby:4.0.1-alpine3.23
2
2
 
3
3
  WORKDIR /wp2txt
4
4
  COPY . ./
5
- RUN rm -Rf wp2txt/Gemfile.lock
5
+ RUN rm -f Gemfile.lock
6
6
 
7
+ # Install dependencies (git is required by gemspec's `git ls-files`)
7
8
  RUN apk update && \
8
9
  apk upgrade && \
9
- apk add --no-cache linux-headers libxml2-dev make gcc libc-dev bash && \
10
- apk add --no-cache -t .build-packages --no-cache build-base curl-dev wget gcompat && \
11
- bundle install -j4
10
+ apk add --no-cache \
11
+ linux-headers libxml2-dev make gcc libc-dev bash \
12
+ sqlite-dev git && \
13
+ apk add --no-cache -t .build-packages \
14
+ build-base curl-dev wget && \
15
+ git init && git add -A && \
16
+ bundle install -j4 && \
17
+ apk del .build-packages
12
18
 
13
- RUN wget https://fossies.org/linux/privat/lbzip2-2.5.tar.gz -O lbzip2.tar.gz && \
14
- tar -xvf lbzip2.tar.gz && cd lbzip2-2.5 && \
15
- bash configure && make && make install && \
16
- cd .. && rm -rf lbzip2*
19
+ # lbzip2 is not available as an Alpine package; build from source
20
+ RUN apk add --no-cache build-base wget && \
21
+ wget https://github.com/kjn/lbzip2/releases/download/v2.5/lbzip2-2.5.tar.gz -O lbzip2.tar.gz && \
22
+ tar -xf lbzip2.tar.gz && cd lbzip2-2.5 && \
23
+ ./configure && make && make install && \
24
+ cd .. && rm -rf lbzip2* && \
25
+ apk del build-base wget
17
26
 
18
27
  WORKDIR /
19
- ENV PATH $PATH:/wp2txt/bin
28
+ ENV PATH=/wp2txt/bin:$PATH
20
29
  CMD ["bash"]
data/Gemfile CHANGED
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source "http://rubygems.org"
3
+ source "https://rubygems.org"
4
4
 
5
- gem "htmlentities"
6
- gem "nokogiri"
7
- gem "optimist"
8
- gem "parallel"
9
- gem "pastel"
10
- gem "ruby-progressbar"
11
- gem "tty-spinner"
5
+ gemspec