narou 2.0.2 → 2.1.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.

@@ -575,10 +575,11 @@ class ConverterBase
575
575
  #
576
576
  # 必ず下げなければいけないところは強制的に字下げ
577
577
  # 他の部分は全体的に判断して字下げ
578
+ # enable_force_indent が有効なら強制字下げ
578
579
  #
579
580
  def auto_indent(data)
580
581
  data.gsub!(FULL_INDENT_TARGET, " \\1")
581
- if @setting.enable_auto_indent && @inspector.inspect_indent(data)
582
+ if @setting.enable_force_indent || (@setting.enable_auto_indent && @inspector.inspect_indent(data))
582
583
  data.gsub!(/^([^#{AUTO_INDENT_IGNORE_INDENT_CHAR}])/) do
583
584
  # 行頭に三点リーダーの代わりに連続中黒(・・・)が来た場合の対策
584
585
  # https://github.com/whiteleaf7/narou/issues/35
@@ -4,10 +4,24 @@
4
4
  #
5
5
 
6
6
  require "fileutils"
7
+ require "memoist"
7
8
  require_relative "narou"
8
9
  require_relative "helper"
9
10
 
10
11
  class Device
12
+ #
13
+ # デバイスの栞をバックアップするときに使う時に include する
14
+ #
15
+ module BackupBookmarkUtility
16
+ extend Memoist
17
+
18
+ # 栞データを管理するディレクトリのパスを取得
19
+ def get_storage_path
20
+ File.join(Narou.get_misc_dir, "bookmark", @name)
21
+ end
22
+ memoize :get_storage_path
23
+ end
24
+
11
25
  case Helper.determine_os
12
26
  when :windows
13
27
  require_relative "device/library/windows"
@@ -45,6 +59,7 @@ class Device
45
59
 
46
60
  class UnknownDevice < StandardError; end
47
61
  class SendFailure < StandardError; end
62
+ class DontConneting < StandardError; end
48
63
 
49
64
  def self.exists?(device)
50
65
  DEVICES.include?(device.downcase)
@@ -149,8 +164,6 @@ class Device
149
164
  end
150
165
  end
151
166
 
152
- private
153
-
154
167
  def create_device_check_methods
155
168
  DEVICES.keys.each do |name|
156
169
  instance_eval <<-EOS
@@ -160,4 +173,5 @@ class Device
160
173
  EOS
161
174
  end
162
175
  end
176
+ private :create_device_check_methods
163
177
  end
@@ -0,0 +1,20 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2013 whiteleaf. All rights reserved.
4
+ #
5
+
6
+ #
7
+ # multi-device で単純なEPUB変換をしたい場合用
8
+ #
9
+ module Device::Epub
10
+ PHYSICAL_SUPPORT = false
11
+ VOLUME_NAME = nil
12
+ DOCUMENTS_PATH_LIST = nil
13
+ EBOOK_FILE_EXT = ".epub"
14
+ NAME = "EPUB"
15
+ DISPLAY_NAME = "EPUB"
16
+
17
+ RELATED_VARIABLES = {
18
+ "force.enable_half_indent_bracket" => false,
19
+ }
20
+ end
@@ -15,15 +15,11 @@ module Device::Ibooks
15
15
 
16
16
  RELATED_VARIABLES = {
17
17
  "force.enable_half_indent_bracket" => false,
18
- "force.enable_add_date_to_title" => false, # タイトルを変えてもiBooksに反映されないため
19
18
  }
20
19
 
21
20
  def hook_change_settings(&original_func)
22
21
  @@__already_exec_change_settings ||= false
23
22
  return if @@__already_exec_change_settings
24
- force_change_settings_function({
25
- "force.enable_half_indent_bracket" => false,
26
- })
27
23
  @@__ibooks_container_dir = File.expand_path(IBOOKS_CONTAINER_DIR)
28
24
  unless File.exist?(@@__ibooks_container_dir)
29
25
  error "iBooksの管理フォルダが見つかりませんでした。" \
@@ -3,6 +3,8 @@
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
5
5
 
6
+ require "fileutils"
7
+
6
8
  module Device::Kindle
7
9
  PHYSICAL_SUPPORT = true
8
10
  VOLUME_NAME = "Kindle"
@@ -14,4 +16,22 @@ module Device::Kindle
14
16
  RELATED_VARIABLES = {
15
17
  "force.enable_half_indent_bracket" => true,
16
18
  }
19
+
20
+ include Device::BackupBookmarkUtility
21
+
22
+ def backup_bookmark
23
+ documents_path = get_documents_path
24
+ raise Device::DontConneting unless documents_path
25
+ paths = Dir.glob(File.join(documents_path, "*.sdr/*.azw3{f,r}"))
26
+ Helper.copy_files(paths, get_storage_path)
27
+ paths.size
28
+ end
29
+
30
+ def restore_bookmark
31
+ documents_path = get_documents_path
32
+ raise Device::DontConneting unless documents_path
33
+ paths = Dir.glob(File.join(get_storage_path, "*.sdr/*"))
34
+ Helper.copy_files(paths, documents_path)
35
+ paths.size
36
+ end
17
37
  end
@@ -11,12 +11,7 @@ module Device::Reader
11
11
  NAME = "Reader"
12
12
  DISPLAY_NAME = "SonyReader"
13
13
 
14
- def hook_change_settings(&original_func)
15
- @@__already_exec_change_settings ||= false
16
- return if @@__already_exec_change_settings
17
- force_change_settings_function({
18
- "force.enable_half_indent_bracket" => false,
19
- })
20
- @@__already_exec_change_settings = true
21
- end
14
+ RELATED_VARIABLES = {
15
+ "force.enable_half_indent_bracket" => false,
16
+ }
22
17
  end
@@ -238,6 +238,25 @@ module Helper
238
238
  TYPE_OF_VALUE[value.class]
239
239
  end
240
240
 
241
+ #
242
+ # ファイルを指定したディレクトリにまとめてコピーする
243
+ # 指定したディレクトリが存在しなければ作成する
244
+ #
245
+ # from: ファイルパスをまとめた Array
246
+ # dest_dir: コピー先のディレクトリ
247
+ #
248
+ def copy_files(from, dest_dir)
249
+ from.each do |path|
250
+ basename = File.basename(path)
251
+ dirname = File.basename(File.dirname(path))
252
+ save_dir = File.join(dest_dir, dirname)
253
+ unless File.directory?(save_dir)
254
+ FileUtils.mkdir_p(save_dir)
255
+ end
256
+ FileUtils.copy(path, File.join(save_dir, basename))
257
+ end
258
+ end
259
+
241
260
  #
242
261
  # 外部コマンド実行中の待機ループの処理を書けるクラス
243
262
  #
@@ -18,9 +18,18 @@ end
18
18
  module Narou end unless defined?(Narou)
19
19
 
20
20
  module Narou::LoggerModule
21
+ attr_accessor :capturing
22
+
21
23
  def initialize
22
24
  super
23
25
  @is_silent = false
26
+ @capturing = false
27
+ end
28
+
29
+ def copy_instance
30
+ self.class.new.tap { |obj|
31
+ obj.silent = silent
32
+ }
24
33
  end
25
34
 
26
35
  def silent=(enable)
@@ -55,18 +64,26 @@ module Narou::LoggerModule
55
64
  # 標準出力($stdout)のバッファリング+取得
56
65
  #
57
66
  # キャプチャー用途なので標準エラーはキャプチャーしない
67
+ # quiet :: 標準出力に出力をしないかどうか
58
68
  # ansicolor_strip :: エスケープシーケンスを除去するか
59
69
  #
60
- def capture(ansicolor_strip = true, &block)
70
+ def capture(options = {}, &block)
71
+ options = {
72
+ quiet: true, ansicolor_strip: true
73
+ }.merge(options)
61
74
  raise "#capture block given" unless block
62
75
  temp_stream = $stdout
63
- $stdout = self.class.new
64
- $stdout.silence do
76
+ $stdout = (self == $stdout ? copy_instance : self)
77
+ $stdout.capturing = true
78
+ if options[:quiet]
79
+ $stdout.silence { block.call }
80
+ else
65
81
  block.call
66
82
  end
83
+ $stdout.capturing = false
67
84
  buffer = $stdout.string
68
85
  $stdout = temp_stream
69
- ansicolor_strip ? strip_color(buffer) : buffer
86
+ options[:ansicolor_strip] ? strip_color(buffer) : buffer
70
87
  end
71
88
 
72
89
  def strip_color(str)
@@ -4,6 +4,7 @@
4
4
  #
5
5
 
6
6
  require "fileutils"
7
+ require "memoist"
7
8
  require_relative "helper"
8
9
  require_relative "inventory"
9
10
  if Helper.engine_jruby?
@@ -11,24 +12,22 @@ if Helper.engine_jruby?
11
12
  end
12
13
 
13
14
  module Narou
15
+ extend Memoist
16
+
14
17
  module_function
15
18
 
16
19
  LOCAL_SETTING_DIR = ".narou"
17
20
  GLOBAL_SETTING_DIR = ".narousetting"
18
21
  AOZORAEPUB3_JAR_NAME = "AozoraEpub3.jar"
19
- AOZORAEPUB3_DIR = "./AozoraEpub3"
20
- PRESET_DIR = "./preset"
22
+ AOZORAEPUB3_DIR = "AozoraEpub3"
23
+ PRESET_DIR = "preset"
24
+ MISC_DIR = "misc"
21
25
  EXIT_ERROR_CODE = 127
22
26
 
23
- @@root_dir = nil
24
- @@local_setting_dir = nil
25
- @@global_setting_dir = nil
26
- @@aozora_jar_path = nil
27
- @@preset_dir = nil
28
27
  @@is_web = false
29
28
 
30
29
  def get_root_dir
31
- return @@root_dir if @@root_dir
30
+ root_dir = nil
32
31
  path = File.expand_path(File.dirname("."))
33
32
  drive_letter = ""
34
33
  if Helper.os_windows?
@@ -37,35 +36,38 @@ module Narou
37
36
  end
38
37
  while path != ""
39
38
  if File.directory?("#{drive_letter}#{path}/#{LOCAL_SETTING_DIR}")
40
- @@root_dir = drive_letter + path
39
+ root_dir = drive_letter + path
41
40
  break
42
41
  end
43
42
  path.gsub!(%r!/[^/]*$!, "")
44
43
  end
45
- @@root_dir
44
+ root_dir
46
45
  end
46
+ memoize :get_root_dir
47
47
 
48
48
  def get_local_setting_dir
49
- return @@local_setting_dir if @@local_setting_dir
49
+ local_setting_dir = nil
50
50
  root_dir = get_root_dir
51
51
  if root_dir
52
- @@local_setting_dir = File.join(root_dir, LOCAL_SETTING_DIR)
52
+ local_setting_dir = File.join(root_dir, LOCAL_SETTING_DIR)
53
53
  end
54
- @@local_setting_dir
54
+ local_setting_dir
55
55
  end
56
+ memoize :get_local_setting_dir
56
57
 
57
58
  def get_global_setting_dir
58
- return @@global_setting_dir if @@global_setting_dir
59
- @@global_setting_dir = File.expand_path(File.join("~", GLOBAL_SETTING_DIR))
60
- unless File.exist?(@@global_setting_dir)
61
- FileUtils.mkdir(@@global_setting_dir)
59
+ global_setting_dir = File.expand_path(File.join("~", GLOBAL_SETTING_DIR))
60
+ unless File.exist?(global_setting_dir)
61
+ FileUtils.mkdir(global_setting_dir)
62
62
  end
63
- @@global_setting_dir
63
+ global_setting_dir
64
64
  end
65
+ memoize :get_global_setting_dir
65
66
 
66
67
  def get_script_dir
67
- @@script_dir ||= File.expand_path(File.join(File.dirname(__FILE__), ".."))
68
+ File.expand_path(File.join(File.dirname(__FILE__), ".."))
68
69
  end
70
+ memoize :get_script_dir
69
71
 
70
72
  def already_init?
71
73
  !!get_root_dir
@@ -92,10 +94,9 @@ module Narou
92
94
  end
93
95
 
94
96
  def get_preset_dir
95
- return @@preset_dir if @@preset_dir
96
- @@preset_dir = File.expand_path(File.join(get_script_dir, PRESET_DIR))
97
- @@preset_dir
97
+ File.expand_path(File.join(get_script_dir, PRESET_DIR))
98
98
  end
99
+ memoize :get_preset_dir
99
100
 
100
101
  def create_aozoraepub3_jar_path(*paths)
101
102
  File.expand_path(File.join(*paths, AOZORAEPUB3_JAR_NAME))
@@ -113,24 +114,22 @@ module Narou
113
114
  # 3. スクリプト保存ディレクトリ(Narou.get_script_dir) 直下の AozoraEpub3
114
115
  #
115
116
  def get_aozoraepub3_path
116
- return @@aozora_jar_path if @@aozora_jar_path
117
117
  global_setting_aozora_path = Inventory.load("global_setting", :global)["aozoraepub3dir"]
118
118
  if global_setting_aozora_path
119
119
  aozora_jar_path = create_aozoraepub3_jar_path(global_setting_aozora_path)
120
120
  if File.exist?(aozora_jar_path)
121
- @@aozora_jar_path = aozora_jar_path
122
121
  return aozora_jar_path
123
122
  end
124
123
  end
125
124
  [Narou.get_root_dir, Narou.get_script_dir].each do |dir|
126
125
  aozora_jar_path = create_aozoraepub3_jar_path(dir, AOZORAEPUB3_DIR)
127
126
  if File.exist?(aozora_jar_path)
128
- @@aozora_jar_path = aozora_jar_path
129
127
  return aozora_jar_path
130
128
  end
131
129
  end
132
130
  nil
133
131
  end
132
+ memoize :get_aozoraepub3_path
134
133
 
135
134
  def create_novel_filename(novel_data, ext = "")
136
135
  author, title = %w(author title).map { |k|
@@ -150,6 +149,11 @@ module Narou
150
149
  File.join(dir, create_novel_filename(data, ext))
151
150
  end
152
151
 
152
+ def get_misc_dir
153
+ File.join(get_root_dir, MISC_DIR)
154
+ end
155
+ memoize :get_misc_dir
156
+
153
157
  require_relative "device"
154
158
 
155
159
  def get_device(device_name = nil)
@@ -289,10 +289,8 @@ class NovelConverter
289
289
  end
290
290
  end
291
291
  # タイトルに完結したかどうかを付加する
292
- flags = data["flags"] || {}
293
292
  tags = data["tags"] || []
294
- flags["end"] ||= tags.include?("end")
295
- if flags["end"]
293
+ if tags.include?("end")
296
294
  processed_title += " (完結)"
297
295
  end
298
296
  # タイトルがルビ化されてしまうのを抑制
@@ -197,6 +197,12 @@ class NovelSetting
197
197
  value: true,
198
198
  help: "自動行頭字下げ機能。行頭字下げが行われているかを判断し、適切に行頭字下げをする"
199
199
  },
200
+ {
201
+ name: "enable_force_indent",
202
+ type: :boolean,
203
+ value: false,
204
+ help: "行頭字下げを必ず行う。enable_auto_indent の設定は無視される"
205
+ },
200
206
  {
201
207
  name: "enable_auto_join_in_brackets",
202
208
  type: :boolean,
@@ -3,5 +3,5 @@
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
5
5
 
6
- Version = "2.0.2"
6
+ Version = "2.1.0"
7
7
 
@@ -486,7 +486,7 @@ class Narou::AppServer < Sinatra::Base
486
486
  ids.each do |id|
487
487
  # セキュリティ的にWEB UIでは独自の差分表示のみ使う
488
488
  CommandLine.run!(["diff", "--no-tool", id])
489
- print "<hr>"
489
+ Helper.print_horizontal_rule
490
490
  end
491
491
  end
492
492
  end
@@ -8,8 +8,18 @@ require_relative "../helper"
8
8
  module Helper
9
9
  module_function
10
10
 
11
+ class << self
12
+ alias :original_print_horizontal_rule :print_horizontal_rule
13
+ end
14
+
11
15
  def print_horizontal_rule
12
- print "<hr>"
16
+ # タグがキャプチャーされると困るので、キャプチャ専用の出力とWEBへの出力は分ける
17
+ if $stdout.capturing
18
+ $stdout.silence do
19
+ original_print_horizontal_rule
20
+ end
21
+ end
22
+ $stdout.push_server.send_all(echo: "<hr>")
13
23
  end
14
24
  end
15
25
 
@@ -536,25 +536,32 @@ var Narou = (function() {
536
536
 
537
537
  init_events_progressbar: function() {
538
538
  var self = this;
539
- var create_progress_html = function() {
540
- return '<div class="progress"><div class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%"></div></div>';
541
- };
542
539
  var $progress = null;
540
+ var createProgressHtml = function(percent) {
541
+ return '<div class="progress"><div class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="' + percent + '" aria-valuemin="0" aria-valuemax="100" style="width:' + percent + '%"></div></div>';
542
+ };
543
+ var initializeProgressbar = function(percent) {
544
+ self.puts(createProgressHtml(percent));
545
+ $progress = self.console.find(".progress > div");
546
+ };
543
547
  var setProgressValue = function(step) {
544
548
  $progress.attr("aria-valuenow", step)
545
549
  .width(step + "%");
546
550
  };
547
551
  this.notification.on("progressbar.init", function() {
548
- self.puts(create_progress_html());
549
- $progress = self.console.find(".progress > div");
552
+ initializeProgressbar(0);
550
553
  });
551
554
  this.notification.on("progressbar.step", function(value) {
552
- if (!$progress) return;
553
- setProgressValue(value);
555
+ if ($progress) {
556
+ setProgressValue(value);
557
+ }
558
+ else {
559
+ initializeProgressbar(value);
560
+ }
554
561
  });
555
562
  this.notification.on("progressbar.clear", function() {
556
563
  if (!$progress) return;
557
- // 表示のタイムラグで100%付近のが表示されないまま消えてしまうので、
564
+ // 表示と通信のタイムラグで100%付近のが表示されないまま消えてしまうので、
558
565
  // 演出的にプログレスバーの消去を遅らせて、100%付近まで表示する
559
566
  setProgressValue(100);
560
567
  $progress = null;