narou 3.1.11 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of narou might be problematic. Click here for more details.

@@ -113,20 +113,21 @@ module Command
113
113
  next
114
114
  end
115
115
  if target == "hotentry"
116
- ebook_path = Update.get_newest_hotentry_file_path(device)
116
+ ebook_paths = [Update.get_newest_hotentry_file_path(device)]
117
117
  else
118
- ebook_path = Narou.get_ebook_file_path(target, device.ebook_file_ext)
118
+ ebook_paths = Narou.get_ebook_file_paths(target, device.ebook_file_ext)
119
119
  end
120
- unless ebook_path
120
+ unless ebook_paths[0]
121
121
  error "#{target} は存在しません"
122
122
  next
123
123
  end
124
- unless File.exist?(ebook_path)
125
- error "まだファイル(#{File.basename(ebook_path)})が無いようです" unless send_all
124
+ unless File.exist?(ebook_paths[0])
125
+ error "まだファイル(#{File.basename(ebook_paths[0])})が無いようです" unless send_all
126
126
  next
127
127
  end
128
128
 
129
- if !@options["force"] && !device.ebook_file_old?(ebook_path)
129
+ # TODO: should check all items in ebook_paths
130
+ if !@options["force"] && !device.ebook_file_old?(ebook_paths[0])
130
131
  next
131
132
  end
132
133
  display_target =
@@ -138,23 +139,25 @@ module Command
138
139
  puts "<bold><green>#{display_target}</green></bold>".termcolor
139
140
 
140
141
  print "#{device.name}へ送信しています"
141
- exit_copy = false
142
- copy_to_path = nil
143
- Thread.abort_on_exception = true
144
- Thread.new do
145
- copy_to_path = device.copy_to_documents(ebook_path)
146
- exit_copy = true
147
- end
148
- until exit_copy
149
- print "."
150
- sleep(0.5)
151
- end
152
- puts
153
- if copy_to_path
154
- puts copy_to_path + " へコピーしました"
155
- else
156
- error "#{device.name}が見つからなかったためコピー出来ませんでした"
157
- exit Narou::EXIT_ERROR_CODE # next しても次も失敗すると分かりきっているためここで終了する
142
+ ebook_paths.each do |ebook_path|
143
+ exit_copy = false
144
+ copy_to_path = nil
145
+ Thread.abort_on_exception = true
146
+ Thread.new do
147
+ copy_to_path = device.copy_to_documents(ebook_path)
148
+ exit_copy = true
149
+ end
150
+ until exit_copy
151
+ print "."
152
+ sleep(0.5)
153
+ end
154
+ puts
155
+ if copy_to_path
156
+ puts copy_to_path + " へコピーしました"
157
+ else
158
+ error "#{device.name}が見つからなかったためコピー出来ませんでした"
159
+ exit Narou::EXIT_ERROR_CODE # next しても次も失敗すると分かりきっているためここで終了する
160
+ end
158
161
  end
159
162
  end
160
163
  if send_all && @options["backup-bookmark"]
@@ -319,6 +319,7 @@ module Command
319
319
  SETTING_TAB_NAMES = {
320
320
  general: "一般",
321
321
  detail: "詳細",
322
+ webui: "WEB UI",
322
323
  global: "Global",
323
324
  default: "default.*",
324
325
  force: "force.*",
@@ -326,6 +327,7 @@ module Command
326
327
  }
327
328
 
328
329
  SETTING_TAB_INFO = {
330
+ webui: "WEB UI 専用の設定です",
329
331
  global: "Global な設定はユーザープロファイルに保存され、すべての narou コマンドで使われます",
330
332
  default: "default.* 系の設定は個別の変換設定で未設定の項目の挙動を指定することが出来ます",
331
333
  force: "force.* 系の設定は個別設定、default.* 等の設定を無視して反映されるようになります",
@@ -478,22 +480,35 @@ module Command
478
480
  help: "ネタバレ防止機能。ダウンロード時の各話タイトルを伏せ字で表示する",
479
481
  tab: :detail
480
482
  },
481
- "theme" => {
483
+ "normalize-filename" => {
484
+ type: :boolean, help: "ファイル名の文字列をNFCで正規化する。※既存データとの互換性が無くなる可能性があるので、バックアップを取った上で機能を理解の上有効にして下さい",
485
+ tab: :detail,
486
+ },
487
+ "webui.theme" => {
482
488
  type: :select, help: "WEB UI 用テーマ選択",
483
489
  invisible: true,
484
490
  select_keys: Narou.get_theme_names,
485
491
  select_summaries: Narou.get_theme_names,
486
- tab: :general
492
+ tab: :webui
487
493
  },
488
- "normalize-filename" => {
489
- type: :boolean, help: "ファイル名の文字列をNFCで正規化する。※既存データとの互換性が無くなる可能性があるので、バックアップを取った上で機能を理解の上有効にして下さい",
490
- tab: :detail,
494
+ "webui.table.reload-timing" => {
495
+ type: :select, help: "小説リストの更新タイミングを選択。未設定時は1作品ごとに更新",
496
+ invisible: true,
497
+ select_keys: %w(every queue),
498
+ select_summaries: %w(
499
+ 1作品ごとに更新
500
+ キューごとに更新
501
+ ),
502
+ tab: :webui
491
503
  },
492
504
  },
493
505
  global: {
494
506
  "aozoraepub3dir" => {
495
507
  type: :directory, help: "AozoraEpub3のあるフォルダを指定", invisible: true
496
508
  },
509
+ "line-height" => {
510
+ type: :float, help: "行間サイズ(narou init から指定しないと反映されません)", invisible: true
511
+ },
497
512
  "difftool" => {
498
513
  type: :string, help: "Diffで使うツールのパスを指定する",
499
514
  tab: :global
@@ -55,7 +55,7 @@ module Command
55
55
 
56
56
  # foo タグ及び bar タグが両方付いた小説のみ更新(タグのAND指定)
57
57
  narou tag foo bar | narou u
58
- narou l -t "foo bar" | narou # こっちでも同じ(覚えやすい方を使う)
58
+ narou l -t "foo bar" | narou u # こっちでも同じ(覚えやすい方を使う)
59
59
 
60
60
  Options:
61
61
  EOS
@@ -35,7 +35,7 @@ module Command
35
35
 
36
36
  def update_narou_novels
37
37
  @narou_novels.each do |api_url, ncodes|
38
- api = Narou::API.new(api_url: api_url, ncodes: ncodes, of: "nu-gl")
38
+ api = Narou::API.new(api_url: api_url, ncodes: ncodes, of: "nu-gl-l")
39
39
  api.request.each do |result|
40
40
  ncode = result["ncode"]
41
41
  data = Downloader.get_data_by_target(ncode)
@@ -43,6 +43,7 @@ module Command
43
43
  if result["novelupdated_at"] > last_check_date
44
44
  data["novelupdated_at"] = result["novelupdated_at"]
45
45
  data["general_lastup"] = result["general_lastup"]
46
+ data["length"] = result["length"]
46
47
  tags = data["tags"] ||= []
47
48
  tags << Narou::MODIFIED_TAG unless tags.include?(Narou::MODIFIED_TAG)
48
49
  end
@@ -64,10 +65,10 @@ module Command
64
65
  next unless downloader.get_latest_table_of_contents(through_error: true)
65
66
  dates = {
66
67
  "novelupdated_at" => downloader.get_novelupdated_at,
67
- "general_lastup" => downloader.get_general_lastup
68
+ "general_lastup" => downloader.get_general_lastup,
69
+ "length" => downloader.novel_length
68
70
  }
69
71
  rescue OpenURI::HTTPError, Errno::ECONNRESET
70
- downloader.setting.clear
71
72
  next
72
73
  end
73
74
  data = @database[id]
@@ -1314,7 +1314,6 @@ class ConverterBase
1314
1314
  (io = after_convert(io)).rewind
1315
1315
  data = replace_by_replace_txt(io.read)
1316
1316
  data = insert_separator_for_selection(data)
1317
- data = double_dash_to_image(data, output_text_dir)
1318
1317
  return data
1319
1318
  end
1320
1319
 
@@ -1430,38 +1429,6 @@ class ConverterBase
1430
1429
  result
1431
1430
  end
1432
1431
 
1433
- DASH_FILES = %w(singledash.png doubledash.png)
1434
-
1435
- def double_dash_to_image(text, output_text_dir)
1436
- return text unless @setting.enable_double_dash_to_image
1437
- # サブタイトルの中の場合は無視する
1438
- # (サブタイトルは文字を大きくしているので、画像の位置がずれてしまうため)
1439
- return text if @text_type == "subtitle"
1440
-
1441
- begin
1442
- # AozoraEpub3 は相対パスじゃないとエラーになるので相対パスに変換
1443
- dash_paths = dash_image_relative_paths(Narou.get_preset_dir, output_text_dir)
1444
- rescue ArgumentError => e
1445
- if e.message =~ /^different prefix/
1446
- # Windowsにおいて、スクリプト本体のあるドライブと小説フォルダがあるドライブが
1447
- # 違う場合、相対パスを計算できなくなる。そのための対処として、.narou ディレクトリ
1448
- # に画像データをコピーし、同一ドライブ内で相対パスを取れるようにする
1449
- copy_dash_images_to_local_setting_dir
1450
- dash_paths = dash_image_relative_paths(Narou.local_setting_dir, output_text_dir)
1451
- else
1452
- raise
1453
- end
1454
- end
1455
- text.gsub(/―{2,}/) do |match|
1456
- len = match.length
1457
- result = "※[#(#{dash_paths[1]})]" * (len / 2)
1458
- if len.odd?
1459
- result += "※[#(#{dash_paths[0]})]"
1460
- end
1461
- result
1462
- end
1463
- end
1464
-
1465
1432
  def dash_image_relative_paths(base_dir, output_text_dir)
1466
1433
  DASH_FILES.map do |name|
1467
1434
  pathname = Pathname(File.join(base_dir, name))
@@ -579,6 +579,17 @@ class Downloader
579
579
  end
580
580
  end
581
581
 
582
+ #
583
+ # 小説の文字数
584
+ #
585
+ # 小説情報から取得するため、実際に計算するわけではない。
586
+ # 情報から取得出来ない(記載がない)場合は無視する
587
+ #
588
+ def novel_length
589
+ info = @setting["info"] || {}
590
+ info["length"]
591
+ end
592
+
582
593
  #
583
594
  # データベース更新
584
595
  #
@@ -599,6 +610,7 @@ class Downloader
599
610
  "general_firstup" => info["general_firstup"],
600
611
  "novelupdated_at" => get_novelupdated_at,
601
612
  "general_lastup" => get_general_lastup,
613
+ "length" => novel_length,
602
614
  }
603
615
  if @@database[@id]
604
616
  @@database[@id].merge!(data)
@@ -884,7 +896,11 @@ class Downloader
884
896
  end
885
897
 
886
898
  def title_to_filename(title)
887
- Helper.replace_filename_special_chars(Helper.truncate_path(title))
899
+ Helper.replace_filename_special_chars(
900
+ Helper.truncate_path(
901
+ HTML.new(title).delete_ruby_tag
902
+ )
903
+ )
888
904
  end
889
905
 
890
906
  #
@@ -916,7 +932,7 @@ class Downloader
916
932
  "href" => @setting["href"],
917
933
  "chapter" => @setting["chapter"].to_s,
918
934
  "subchapter" => @setting["subchapter"].to_s,
919
- "subtitle" => @setting["subtitle"].gsub("\n", ""),
935
+ "subtitle" => slim_subtitle(@setting["subtitle"]),
920
936
  "file_subtitle" => title_to_filename(@setting["subtitle"]),
921
937
  "subdate" => subdate,
922
938
  "subupdate" => @setting["subupdate"]
@@ -933,7 +949,7 @@ class Downloader
933
949
  "index" => "1",
934
950
  "href" => @setting.replace_group_values("href", "index" => "1"),
935
951
  "chapter" => "",
936
- "subtitle" => @setting["title"],
952
+ "subtitle" => slim_subtitle(@setting["title"]),
937
953
  "file_subtitle" => title_to_filename(@setting["title"]),
938
954
  "subdate" => info["general_firstup"],
939
955
  "subupdate" => info["novelupdated_at"] || info["general_lastup"] || info["general_firstup"]
@@ -941,6 +957,11 @@ class Downloader
941
957
  [subtitle]
942
958
  end
943
959
 
960
+ def slim_subtitle(string)
961
+ # HTML.new(string).delete_ruby_tag.delete("\n")
962
+ HTML.new(string).delete_ruby_tag.delete("\n")
963
+ end
964
+
944
965
  #
945
966
  # 小説本文をまとめてダウンロードして保存
946
967
  #
@@ -971,7 +992,7 @@ class Downloader
971
992
  @stream.print "短編 "
972
993
  end
973
994
  printable_subtitle = @gurad_spoiler ? Helper.to_unprintable_words(subtitle) : subtitle
974
- @stream.print "#{printable_subtitle} (#{i+1}/#{max})"
995
+ @stream.print "#{HTML.new(printable_subtitle).delete_ruby_tag} (#{i + 1}/#{max})"
975
996
 
976
997
  section_file_name = "#{index} #{file_subtitle}.yaml"
977
998
  section_file_relative_path = File.join(SECTION_SAVE_DIR_NAME, section_file_name)
@@ -294,7 +294,7 @@ module Helper
294
294
  when Time
295
295
  date
296
296
  when String
297
- Time.parse(date.sub(/[\((].+?[\))]/, "").tr("年月日時分秒@;", "///::: :"))
297
+ Time.parse(date.sub(/[\((].+?[\))]/, "").tr("年月日時分秒@;", "///::: :")).getlocal
298
298
  end
299
299
  rescue ArgumentError
300
300
  nil
@@ -325,7 +325,7 @@ module Helper
325
325
  # 数字やスペース、句読点、感嘆符はそのままにする
326
326
  #
327
327
  def to_unprintable_words(string, mask = "●")
328
- result = ""
328
+ result = "".dup
329
329
  string.each_char do |char|
330
330
  result += case char
331
331
  when /[0-90-9  、。!?!?]/
@@ -354,6 +354,23 @@ module Helper
354
354
  end
355
355
  end
356
356
 
357
+ #
358
+ # src をERBとして読み込んでから dst に書き出す
359
+ #
360
+ def erb_copy(src, dst, _binding)
361
+ data = File.read(src, mode: "r:BOM|UTF-8")
362
+ result = ERB.new(data, nil, "-").result(_binding)
363
+ File.write(dst, result)
364
+ end
365
+
366
+ #
367
+ # カンマ付き数字列を数値に変換
368
+ #
369
+ def numeric_length(len)
370
+ return len unless len.is_a?(String)
371
+ len.delete(",").to_i
372
+ end
373
+
357
374
  #
358
375
  # 外部コマンド実行中の待機ループの処理を書けるクラス
359
376
  #
@@ -103,4 +103,8 @@ class HTML
103
103
  def em_to_sesame(text = @string)
104
104
  text.gsub(%r!<em class="emphasisDots">(.+?)</em>!, "[#傍点]\\1[#傍点終わり]")
105
105
  end
106
+
107
+ def delete_ruby_tag(text = @string)
108
+ text.gsub(%r!<\/?(?:ruby|rb|rp|rt)>!, "")
109
+ end
106
110
  end
@@ -5,6 +5,7 @@
5
5
 
6
6
  require "fileutils"
7
7
  require "memoist"
8
+ require "active_support/core_ext/object/blank"
8
9
  require_relative "helper"
9
10
  require_relative "inventory"
10
11
  if Helper.engine_jruby?
@@ -23,6 +24,7 @@ module Narou
23
24
  EXIT_INTERRUPT = 126
24
25
  EXIT_REQUEST_REBOOT = 125
25
26
  MODIFIED_TAG = "modified"
27
+ LINE_HEIGHT_DEFAULT = 1.6 # 単位em
26
28
 
27
29
  UPDATE_SORT_KEYS = {
28
30
  "id" => "ID", "last_update" => "更新日", "title" => "タイトル", "author" => "作者名",
@@ -35,7 +37,7 @@ module Narou
35
37
  @@is_web = false
36
38
 
37
39
  def last_commit_year
38
- 2017
40
+ 2018
39
41
  end
40
42
 
41
43
  def get_root_dir
@@ -199,7 +201,15 @@ module Narou
199
201
  #
200
202
  def create_novel_filename(novel_data, ext = "")
201
203
  filename_to_ncode = Inventory.load("local_setting")["convert.filename-to-ncode"]
202
- if filename_to_ncode
204
+ novel_setting =
205
+ if novel_data["id"]
206
+ NovelSetting.load(novel_data["id"])
207
+ else
208
+ OpenStruct.new
209
+ end
210
+ if novel_setting.output_filename.present?
211
+ %!#{novel_setting.output_filename}#{ext}!
212
+ elsif filename_to_ncode
203
213
  ncode, domain = novel_data["ncode"], novel_data["domain"]
204
214
  if !ncode || !domain
205
215
  id = novel_data["id"]
@@ -213,22 +223,39 @@ module Narou
213
223
  serialized_domain = domain.to_s.gsub(".", "_")
214
224
  %!#{serialized_domain}_#{ncode}#{ext}!
215
225
  else
216
- author, title = %w(author title).map { |k|
217
- Helper.replace_filename_special_chars(novel_data[k], true)
218
- }
226
+ author = Helper.replace_filename_special_chars(
227
+ novel_setting.novel_author.presence || novel_data["author"],
228
+ true
229
+ )
230
+ title = Helper.replace_filename_special_chars(
231
+ novel_setting.novel_title.presence || novel_data["title"],
232
+ true
233
+ )
219
234
  "[#{author}] #{title}#{ext}"
220
235
  end
221
236
  end
222
237
 
223
- def get_mobi_path(target)
224
- get_ebook_file_path(target, ".mobi")
238
+ def get_mobi_paths(target)
239
+ get_ebook_file_paths(target, ".mobi")
225
240
  end
226
241
 
227
- def get_ebook_file_path(target, ext)
242
+ def get_ebook_file_paths(target, ext)
228
243
  data = Downloader.get_data_by_target(target)
229
244
  return nil unless data
230
245
  dir = Downloader.get_novel_data_dir_by_target(target)
231
- File.join(dir, create_novel_filename(data, ext))
246
+ fname = create_novel_filename(data, ext)
247
+ base = File.basename(fname, ext)
248
+ get_ebook_file_paths_from_components(dir, base, ext)
249
+ end
250
+
251
+ def get_ebook_file_paths_from_components(dir, base, ext)
252
+ paths = [File.join(dir, "#{base}#{ext}")]
253
+ index = 2
254
+ while File.exist?(path = File.join(dir, "#{base}_#{index}#{ext}"))
255
+ paths.push(path)
256
+ index += 1
257
+ end
258
+ paths
232
259
  end
233
260
 
234
261
  def get_misc_dir
@@ -262,7 +289,7 @@ module Narou
262
289
  end
263
290
 
264
291
  def get_theme
265
- Inventory.load("local_setting")["theme"]
292
+ Inventory.load("local_setting")["webui.theme"]
266
293
  end
267
294
 
268
295
  def get_theme_dir(name = nil)
@@ -311,5 +338,10 @@ module Narou
311
338
  end
312
339
  memoize :kindlegen_path
313
340
 
341
+ def line_height
342
+ global_setting = Inventory.load("global_setting", :global)
343
+ global_setting["line-height"] || LINE_HEIGHT_DEFAULT
344
+ end
345
+
314
346
  end
315
347
  end
@@ -25,6 +25,16 @@ class NovelConverter
25
25
 
26
26
  attr_reader :use_dakuten_font
27
27
 
28
+ def self.extensions_of_converted_files(device)
29
+ exts = [".txt"]
30
+ if device && device.kobo?
31
+ exts.push(device.ebook_file_ext)
32
+ else
33
+ exts.push(".epub", device.ebook_file_ext)
34
+ end
35
+ exts
36
+ end
37
+
28
38
  #
29
39
  # 指定の小説を整形・変換する
30
40
  #
@@ -38,7 +48,7 @@ class NovelConverter
38
48
  if setting
39
49
  novel_converter = new(setting, options[:output_filename], options[:display_inspector])
40
50
  return {
41
- converted_txt_path: novel_converter.convert_main,
51
+ converted_txt_paths: novel_converter.convert_main,
42
52
  use_dakuten_font: novel_converter.use_dakuten_font
43
53
  }
44
54
  end
@@ -69,22 +79,28 @@ class NovelConverter
69
79
  text.force_encoding(options[:encoding]).encode!(Encoding::UTF_8)
70
80
  end
71
81
  {
72
- converted_txt_path: novel_converter.convert_main(text),
82
+ converted_txt_paths: novel_converter.convert_main(text),
73
83
  use_dakuten_font: novel_converter.use_dakuten_font
74
84
  }
75
85
  end
76
86
 
77
87
  DAKUTEN_FROM = ["vertical_font_with_dakuten.css", "DMincho.ttf"]
78
88
  DAKUTEN_TO = ["template/OPS/css_custom/vertical_font.css", "template/OPS/fonts/DMincho.ttf"]
89
+ DAKUTEN_ERB = [true, false]
79
90
 
80
91
  def self.activate_dakuten_font_files
81
92
  preset_dir = Narou.get_preset_dir
82
93
  aozora_dir = File.dirname(Narou.get_aozoraepub3_path)
94
+ line_height = Narou.line_height
83
95
 
84
96
  DAKUTEN_FROM.each_with_index do |name, i|
85
97
  src = File.join(preset_dir, name)
86
98
  dst = File.join(aozora_dir, DAKUTEN_TO[i])
87
- FileUtils.copy(src, dst)
99
+ if DAKUTEN_ERB[i]
100
+ Helper.erb_copy(src, dst, binding)
101
+ else
102
+ FileUtils.copy(src, dst)
103
+ end
88
104
  end
89
105
  end
90
106
 
@@ -92,8 +108,9 @@ class NovelConverter
92
108
  preset_dir = Narou.get_preset_dir
93
109
  aozora_dir = File.dirname(Narou.get_aozoraepub3_path)
94
110
  path_normal_vertical_css = File.join(preset_dir, "vertical_font.css")
111
+ line_height = Narou.line_height
95
112
 
96
- FileUtils.copy(path_normal_vertical_css, File.join(aozora_dir, DAKUTEN_TO[0]))
113
+ Helper.erb_copy(path_normal_vertical_css, File.join(aozora_dir, DAKUTEN_TO[0]), binding)
97
114
  FileUtils.remove(File.join(aozora_dir, DAKUTEN_TO[1]))
98
115
  end
99
116
 
@@ -305,7 +322,7 @@ class NovelConverter
305
322
  else
306
323
  epub_ext = ".epub"
307
324
  end
308
- epub_path = txt_path.sub(/.txt$/, epub_ext)
325
+ epub_path = txt_path.sub(/\.txt$/, epub_ext)
309
326
 
310
327
  if !device || !device.kindle? || options[:no_mobi]
311
328
  puts File.basename(epub_path) + " を出力しました"
@@ -348,9 +365,10 @@ class NovelConverter
348
365
  def initialize(setting, output_filename = nil, display_inspector = false, output_text_dir = nil)
349
366
  @setting = setting
350
367
  @novel_id = setting.id
351
- @novel_author = setting.include?("novel_author") ? setting["novel_author"] : setting.author
352
- @novel_title = setting.include?("novel_title") ? setting["novel_title"] : setting.title
368
+ @novel_author = setting.novel_author.empty? ? setting.author : setting.novel_author
369
+ @novel_title = setting.novel_title.empty? ? setting.title : setting.novel_title
353
370
  @output_filename = (output_filename || setting.output_filename)
371
+ @output_filename = nil if @output_filename.empty?
354
372
  @inspector = Inspector.new(@setting)
355
373
  @illustration = Illustration.new(@setting, @inspector)
356
374
  @display_inspector = display_inspector
@@ -368,32 +386,35 @@ class NovelConverter
368
386
  initialize_event
369
387
 
370
388
  if text
371
- converted_text = convert_main_for_text(text)
389
+ array_of_converted_text = convert_main_for_text(text)
372
390
  else
373
- converted_text = convert_main_for_novel
391
+ array_of_converted_text = convert_main_for_novel
374
392
  update_latest_convert_novel
375
393
  end
394
+ inspect_novel(array_of_converted_text)
376
395
 
377
- inspect_novel(converted_text)
378
-
379
- output_path = create_output_path(text, converted_text)
380
- File.write(output_path, converted_text)
396
+ array_of_output_path = []
397
+ array_of_converted_text.each_with_index do |converted_text, i|
398
+ output_path = create_output_path(text, converted_text, i + 1)
399
+ File.write(output_path, converted_text)
400
+ array_of_output_path.push(output_path)
401
+ end
381
402
 
382
403
  display_footer
383
404
 
384
- output_path
405
+ array_of_output_path
385
406
  end
386
407
 
387
408
  def initialize_event
388
409
  progressbar = nil
389
410
 
390
- one(:"convert_main.init") do |subtitles|
411
+ on(:"convert_main.init") do |subtitles|
391
412
  progressbar = ProgressBar.new(subtitles.size)
392
413
  end
393
414
  on(:"convert_main.loop") do |i|
394
415
  progressbar.output(i) if progressbar
395
416
  end
396
- one(:"convert_main.finish") do
417
+ on(:"convert_main.finish") do
397
418
  progressbar.clear if progressbar
398
419
  end
399
420
  end
@@ -419,13 +440,15 @@ class NovelConverter
419
440
 
420
441
  # is_hotentry を有効にすると、テンプレートで作成するテキストファイルに
421
442
  # あらすじ、作品タイトル、本の読み終わり表示が付与されなくなる
422
- def create_novel_text_by_template(sections, toc, is_hotentry = false)
443
+ def create_novel_text_by_template(sections, toc, is_hotentry = false, index = nil)
423
444
  cover_chuki = create_cover_chuki
424
445
  device = Narou.get_device
425
446
  setting = @setting
426
- toc["title"] = setting["novel_title"] if setting.include?("novel_title")
427
- toc["author"] = setting["novel_author"] if setting.include?("novel_author")
428
- processed_title = decorate_title(toc["title"])
447
+ toc["title"] = setting.novel_title unless setting.novel_title.empty?
448
+ toc["author"] = setting.novel_author unless setting.novel_author.empty?
449
+ processing_title = toc["title"]
450
+ processing_title += "_#{index}" if index
451
+ processed_title = decorate_title(processing_title)
429
452
  tempalte_name = (device && device.ibunko? ? NOVEL_TEXT_TEMPLATE_NAME_FOR_IBUNKO : NOVEL_TEXT_TEMPLATE_NAME)
430
453
  Template.get(tempalte_name, binding, 1.1)
431
454
  end
@@ -543,7 +566,7 @@ class NovelConverter
543
566
  #
544
567
  # 最終的に出力するパスを生成
545
568
  #
546
- def create_output_path(is_text_file_mode, converted_text)
569
+ def create_output_path(is_text_file_mode, converted_text, index)
547
570
  output_path = ""
548
571
  if @output_filename
549
572
  output_path = File.join(@setting.archive_path, File.basename(@output_filename))
@@ -560,9 +583,15 @@ class NovelConverter
560
583
  end
561
584
  filename = Narou.create_novel_filename(info)
562
585
  output_path = File.join(@setting.archive_path, filename)
563
- if output_path !~ /\.\w+$/
564
- output_path += ".txt"
565
- end
586
+ end
587
+ if output_path !~ /\.\w+$/
588
+ output_path += ".txt"
589
+ end
590
+ # change output_path to "basename_#{index}.ext" if index is greater than 1
591
+ if index > 1
592
+ ext = File.extname(output_path)
593
+ output_path = File.join(File.dirname(output_path), File.basename(output_path, ext))
594
+ output_path += "_#{index}#{ext}"
566
595
  end
567
596
  output_path
568
597
  end
@@ -582,7 +611,7 @@ class NovelConverter
582
611
 
583
612
  @use_dakuten_font = @converter.use_dakuten_font
584
613
 
585
- converted_text
614
+ [converted_text]
586
615
  end
587
616
 
588
617
  #
@@ -590,24 +619,43 @@ class NovelConverter
590
619
  #
591
620
  # 引数 subtitles にデータを渡した場合はそれを直接使う
592
621
  # is_hotentry を有効にすると出力されるテキストファイルにあらすじや作品タイトル等が含まれなくなる
622
+ # また、 is_hotentry を有効にすると分割も行われなくなる
593
623
  #
594
624
  def convert_main_for_novel(subtitles = nil, is_hotentry = false)
595
625
  toc = Downloader.get_toc_data(@setting.archive_path)
596
626
  unless subtitles
597
627
  subtitles = cut_subtitles(toc["subtitles"])
598
628
  end
599
- @converter.subtitles = subtitles
600
- toc["story"] = @converter.convert(toc["story"], "story")
601
- html = HTML.new
602
- html.strip_decoration_tag = @setting.enable_strip_decoration_tag
603
- site_setting = SiteSetting.find(toc["toc_url"])
604
- html.set_illust_setting({current_url: site_setting["illust_current_url"],
605
- grep_pattern: site_setting["illust_grep_pattern"]})
606
-
607
- sections = subtitles_to_sections(subtitles, html)
608
- converted_text = create_novel_text_by_template(sections, toc, is_hotentry)
609
-
610
- converted_text
629
+ if is_hotentry == false && @setting.slice_size > 0 && subtitles.length > @setting.slice_size
630
+ puts "#{@setting.slice_size}話ごとに分割して変換します"
631
+ array_of_subtitles = subtitles.each_slice(@setting.slice_size).to_a
632
+ else
633
+ array_of_subtitles = [subtitles]
634
+ end
635
+ array_of_converted_text = []
636
+ array_of_subtitles.each_with_index do |sliced_subtitles, index|
637
+ @converter.subtitles = sliced_subtitles
638
+ toc["story"] = @converter.convert(toc["story"], "story")
639
+ html = HTML.new
640
+ html.strip_decoration_tag = @setting.enable_strip_decoration_tag
641
+ site_setting = SiteSetting.find(toc["toc_url"])
642
+ html.set_illust_setting({ current_url: site_setting["illust_current_url"],
643
+ grep_pattern: site_setting["illust_grep_pattern"] })
644
+
645
+ sections = subtitles_to_sections(sliced_subtitles, html)
646
+ array_of_converted_text.push(
647
+ create_novel_text_by_template(
648
+ sections, toc, is_hotentry,
649
+ array_of_subtitles.length == 1 ? nil : index + 1
650
+ )
651
+ )
652
+ end
653
+
654
+ if is_hotentry
655
+ array_of_converted_text[0]
656
+ else
657
+ array_of_converted_text
658
+ end
611
659
  end
612
660
 
613
661
  def cut_subtitles(subtitles)
@@ -668,8 +716,9 @@ class NovelConverter
668
716
  { "title" => title, "author" => author }
669
717
  end
670
718
 
671
- def inspect_novel(text)
719
+ def inspect_novel(array_of_text)
672
720
  if @setting.enable_inspect
721
+ text = array_of_text.flatten
673
722
  @inspector.inspect_end_touten_conditions(text) # 行末読点の現在状況を調査する
674
723
  @inspector.countup_return_in_brackets(text) # カギ括弧内の改行状況を調査する
675
724
  end