md2site 0.1.2

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 (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +30 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +138 -0
  6. data/.rubocop_todo.yml +47 -0
  7. data/.travis.yml +7 -0
  8. data/Gemfile +8 -0
  9. data/Gemfile.lock +98 -0
  10. data/LICENSE +8 -0
  11. data/LICENSE.txt +8 -0
  12. data/README.md +39 -0
  13. data/Rakefile +6 -0
  14. data/bin/console +14 -0
  15. data/bin/md2site +157 -0
  16. data/bin/setup +8 -0
  17. data/data/conf/conf-sample.yml +5 -0
  18. data/data/conf/conf.sh +32 -0
  19. data/data/conf/setting.yml +3 -0
  20. data/data/conf/site.tsv +1 -0
  21. data/data/template/5col_no_attr.erb +72 -0
  22. data/data/template/5col_no_attr_b.erb +72 -0
  23. data/data/template/functions_static.erb +10 -0
  24. data/data/template/functions_variable.erb +3 -0
  25. data/data/template2/contest_notification.erb +16 -0
  26. data/data/template2/contest_notification_2.erb +34 -0
  27. data/data/template2/contest_winners.erb +69 -0
  28. data/data/template2/contest_winners_statement.erb +1 -0
  29. data/data/testdata/conf-blog.yml +6 -0
  30. data/data/testdata/conf-download.yml +6 -0
  31. data/data/testdata/conf-link.yml +6 -0
  32. data/data/testdata/conf-profile.yml +6 -0
  33. data/data/testdata/conf-top.yml +6 -0
  34. data/data/testdata/site.tsv +5 -0
  35. data/data/testdata0/conf-appliction.yml +1 -0
  36. data/data/testdata0/conf-attempt.yml +69 -0
  37. data/data/testdata0/conf-autosar.yml +11 -0
  38. data/data/testdata0/conf-community.yml +3 -0
  39. data/data/testdata0/conf-document.yml +1 -0
  40. data/data/testdata0/conf-download.yml +1 -0
  41. data/data/testdata0/conf-edu.yml +52 -0
  42. data/data/testdata0/conf-etc.yml +1 -0
  43. data/data/testdata0/conf-members.yml +2 -0
  44. data/data/testdata0/conf-product.yml +37 -0
  45. data/data/testdata0/conf-project.yml +14 -0
  46. data/data/testdata0/conf-rtk.yml +25 -0
  47. data/data/testdata0/conf-top.yml +1 -0
  48. data/data/testdata0/setting.yml +33 -0
  49. data/data/testdata0/site.tsv +123 -0
  50. data/lib/md2site/env.rb +649 -0
  51. data/lib/md2site/htmlutils.rb +142 -0
  52. data/lib/md2site/htmlutils0.rb +223 -0
  53. data/lib/md2site/info.rb +17 -0
  54. data/lib/md2site/init.rb +90 -0
  55. data/lib/md2site/listfile.rb +22 -0
  56. data/lib/md2site/make.rb +295 -0
  57. data/lib/md2site/nkfguess.rb +33 -0
  58. data/lib/md2site/setup.rb +358 -0
  59. data/lib/md2site/statusfile.rb +75 -0
  60. data/lib/md2site/testdata.rb +50 -0
  61. data/lib/md2site/testx.rb +73 -0
  62. data/lib/md2site/version.rb +3 -0
  63. data/lib/md2site.rb +161 -0
  64. data/md2site.gemspec +59 -0
  65. metadata +359 -0
@@ -0,0 +1,649 @@
1
+ module Md2site
2
+ #
3
+ # 環境クラス
4
+ #
5
+ class Env
6
+ require "yaml"
7
+ require "fileutils"
8
+ require "filex"
9
+
10
+ attr_reader :conf_hs
11
+ attr_reader :commands
12
+ attr_reader :category
13
+ attr_reader :category_x
14
+ attr_reader :htmlfile_index
15
+ attr_reader :alias_htmlfile_index
16
+ attr_reader :absolutepath_root
17
+ attr_reader :absolutepath_root_settingfile
18
+
19
+ #
20
+ # 初期化
21
+ # @param [String] conf_path
22
+ # @param mes [Messagex] Messagexクラスのインスタンス
23
+ # @param verbose [Boolean] FileUtilsクラスのメソッドのverbose引数に与える値
24
+ def initialize(conf_path, mes, verbose)
25
+ @mes = mes
26
+ @verbose = verbose
27
+ register_exit_codes
28
+
29
+ @category_struct = Struct.new(:target, :misc, :subTargets, :subTargetsByHtmlfile)
30
+ @target_struct = Struct.new(:name, :dir, :dataDir, :workDir, :materialDir, :htmldir, :htmlfile, :mdfile, :filedir, :except, :command, :aliashtmldir, :aliashtmlfile, :templates)
31
+ @template_struct = Struct.new(:datafname, :templatefname, :outputfname, :macroname, :kind, :src_subtarget_name)
32
+ @filedir = Struct.new(:html_output, :html_input, :partAhtml, :partChtml, :input_md, :output_md, :root_output_md, :data_dir)
33
+ @commands = {}
34
+ @category = {}
35
+ @conf_hs = {}
36
+
37
+ check_conf_path(conf_path)
38
+ setup_from_conf(conf_path, @conf_hs)
39
+
40
+ check_conf_hs_for_attribute(conf_path)
41
+ check_conf_hs_and_set(conf_path)
42
+ check_conf_hs(conf_path)
43
+
44
+ @category_x = setup_category(@conf_hs["ABSOLUTE_PATH_SITE_FILE"])
45
+ setup_config
46
+ end
47
+
48
+ #
49
+ # 終了コードの登録
50
+ #
51
+ # rubocop:disable Metrics/MethodLength
52
+ def register_exit_codes
53
+ @mes.add_exitcode("EXIT_CODE_CANNOT_FIND_CONFFILE")
54
+ @mes.add_exitcode("EXIT_CODE_NOT_SPECIFIED_CONFFILE")
55
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_ABSOLUTE_PATH_ROOT_CONF")
56
+ @mes.add_exitcode("EXIT_CODE_CANNOT_FIND_ROOTCONFFILE")
57
+ @mes.add_exitcode("EXIT_CODE_CANNOT_FIND_DEFAULT_TABLE_TEMPLATE")
58
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_ABSOLUTE_PATH_ROOT_SETTINGFILE")
59
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_ABSOLUTE_PATH_SITE_FILE")
60
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_TEPLATE_DIR")
61
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_CONF_DIR")
62
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_SRC_DIR")
63
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_URL")
64
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_ROOT_TEMPLATE_FUNCTIONS_VARIABLE")
65
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_ABSOLUTE_PATH_STATUS_FILE")
66
+ @mes.add_exitcode("EXIT_CODE_CANNOT_FIND_SITEFILEPATH")
67
+ @mes.add_exitcode("EXIT_CODE_CANNOT_MAKE_ABSOLUTE_PATH_ROOT")
68
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_TARGET_COMMAND_INDEX")
69
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_SUBTARGET_COMMAND_INDEX")
70
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_KEY_INDEX")
71
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_HTMLFILE_INDEX")
72
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_ALIAS_HTMLFILE_INDEX")
73
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_ABSOLUTE_PATH_ROOT")
74
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_CATEGORY_CONF_PREFIX")
75
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_ROOTOUTPUTDIR")
76
+ @mes.add_exitcode("EXIT_CODE_CANNOT_FIND_ROOTOUTPUTDIR")
77
+ @mes.add_exitcode("EXIT_CODE_CANNOT_READ_CONFFNAME")
78
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_DATA_DIR")
79
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_WORK_DIR")
80
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_MATERIAL_DIR")
81
+ @mes.add_exitcode("EXIT_CODE_INVALID_INDEX")
82
+ @mes.add_exitcode("EXIT_CODE_CANNOT_GET_TARGET")
83
+ @mes.add_exitcode("EXIT_CODE_CANNOT_FIND_TARGETCONFYAMLPATH")
84
+ @mes.add_exitcode("EXIT_CODE_NOT_SPECIFIED_LEGAL_TARGET_COMMAND")
85
+ end
86
+ # rubocop:enable Metrics/MethodLength
87
+
88
+ #
89
+ # 有効な構成ファイルへのパスであるか調べる
90
+ # @param conf_path [String] 構成ファイルへのパス
91
+ def check_conf_path(conf_path)
92
+ # rubocop:disable Style/GuardClause
93
+ unless conf_path
94
+ @mes.output_error("Not specified conf file")
95
+ exit(@mes.ec("EXIT_CODE_NOT_SPECIFIED_CONFFILE"))
96
+ end
97
+
98
+ unless File.exist?(conf_path)
99
+ @mes.output_fatal("Cannot find conf file(#{confPath})")
100
+ exit(@mes.ec("EXIT_CODE_CANNOT_FIND_CONFFILE"))
101
+ end
102
+ # rubocop:enable Style/GuardClause
103
+ end
104
+
105
+ #
106
+ # Envクラスのattributeとして有効な値が構成ファイル中に指定されているか調べる
107
+ # @param conf_path [String] 構成ファイルへのパス
108
+ def check_conf_hs_for_attribute(conf_path)
109
+ # rubocop:disable Style/GuardClause
110
+ @absolutepath_root = get_filepath(@conf_hs["ABSOLUTE_PATH_ROOT"])
111
+ if @absolutepath_root.nil?
112
+ @mes.output_fatal("Cannot get absolutePathRoot from #{conf_path}")
113
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_ABSOLUTE_PATH_ROOT"))
114
+ else
115
+ @mes.exc_make_directory(@absolutepath_root) { FileUtils.mkdir_p(@absolutepath_root, verbose: @verbose) }
116
+ end
117
+
118
+ @absolute_path_root_conf = @conf_hs["ABSOLUTE_PATH_ROOT_CONF"]
119
+ unless @absolute_path_root_conf
120
+ @mes.output_fatal("Cannot get ABSOLUTE_PATH_ROOT_CONF in #{conf_path}")
121
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_ABSOLUTE_PATH_ROOT_CONF"))
122
+ end
123
+ unless File.exist?(@absolute_path_root_conf)
124
+ @mes.output_fatal("Cannot find root conf dir(#{@absolute_path_root_conf})")
125
+ exit(@mes.ec("EXIT_CODE_CANNOT_FIND_ROOTCONFFILE"))
126
+ end
127
+
128
+ @absolutepath_root_settingfile = @conf_hs["ABSOLUTE_PATH_ROOT_SETTINGFILE"]
129
+ unless @absolutepath_root_settingfile
130
+ @mes.output_error("Can't get ABSOLUTE_PATH_ROOT_SETTINGFILE in #{conf_path}")
131
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_ABSOLUTE_PATH_ROOT_SETTINGFILE"))
132
+ end
133
+ # rubocop:enable Style/GuardClause
134
+ end
135
+
136
+ #
137
+ # 構成ファイルから変換したハッシュに有効な値が指定されているか調べる
138
+ # @param conf_path [String] 構成ファイルへのパス
139
+ #
140
+ # rubocop:disable Metrics/MethodLength, Style/GuardClause
141
+ def check_conf_hs(conf_path)
142
+ default_table_template = @conf_hs["DEFAULT_TABLE_TEMPLATE"] # 5col_no_attr_b.erb
143
+ unless default_table_template || !FileTest.exist?(default_table_template)
144
+ @mes.output_fatal("Cannot find valid DEFAULT_TABLE_TEMPLATE(=#{default_table_template}) in #{conf_path}")
145
+ exit(@mes.ec("EXIT_CODE_CANNOT_FIND_DEFAULT_TABLE_TEMPLATE"))
146
+ end
147
+
148
+ sitefile_path = @conf_hs["ABSOLUTE_PATH_SITE_FILE"]
149
+ unless sitefile_path || !FileTest.exist?(sitefile_path)
150
+ @mes.output_error("Can't get valid ABSOLUTE_PATH_SITE_FILE in #{conf_path}")
151
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_ABSOLUTE_PATH_SITE_FILE"))
152
+ end
153
+
154
+ absolute_path_status_file = @conf_hs["ABSOLUTE_PATH_STATUS_FILE"]
155
+ unless absolute_path_status_file || !FileTest.exist?(absolute_path_status_file)
156
+ @mes.output_error("Can't find valid ABSOLUTE_PATH_STATUS_FILE in #{conf_path}")
157
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_ABSOLUTE_PATH_STATUS_FILE"))
158
+ end
159
+
160
+ unless @conf_hs["TEMPLELATE_DIR"]
161
+ @mes.output_error("Can't get TEPLATE_DIR in #{conf_path}")
162
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_TEPLATE_DIR"))
163
+ end
164
+
165
+ unless @conf_hs["CONF_DIR"]
166
+ @mes.output_error("Can't get CONF_DIR in #{conf_path}")
167
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_CONF_DIR"))
168
+ end
169
+
170
+ unless @conf_hs["URL"]
171
+ @mes.output_error("Can't get URL in #{conf_path}")
172
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_URL"))
173
+ end
174
+
175
+ unless @conf_hs["ROOT_TEMPLATE_FUNCTIONS_VARIABLE"]
176
+ @mes.output_fatal("Cannot get value by ROOT_TEMPLATE_FUNCTIONS_VARIABLE from #{conf_path}")
177
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_ROOT_TEMPLATE_FUNCTIONS_VARIABLE"))
178
+ end
179
+
180
+ root_output_path = File.join(@absolutepath_root, @root_output_dir)
181
+ unless File.exist?(root_output_path)
182
+ @mes.output_error("Can't find root_output_dir(=#{@root_output_dir})")
183
+ exit(@mes.ec("EXIT_CODE_CANNOT_FIND_ROOTOUTPUTDIR"))
184
+ end
185
+ end
186
+ # rubocop:enable Metrics/MethodLength, Style/GuardClause
187
+
188
+ #
189
+ # 構成ファイルから変換したハッシュに指定されている値が有効であれば、インスタンス変数で参照できるようにする
190
+ # @param conf_path [String] 構成ファイルへのパス
191
+ # rubocop:disable Metrics/MethodLength, Style/GuardClause
192
+ def check_conf_hs_and_set(conf_path)
193
+ @category_conf_prefix = @conf_hs["CATEGORY_CONF_PREFIX"]
194
+ unless @category_conf_prefix
195
+ @mes.output_fatal("Cannot get category conf prefix from #{conf_path}")
196
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_CATEGORY_CONF_PREFIX"))
197
+ end
198
+
199
+ @root_output_dir = @conf_hs["OUTPUT_DIR"]
200
+ unless @root_output_dir
201
+ @mes.output_fatal("Cannot get rootOutputDir from #{conf_path}")
202
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_ROOTOUTPUTDIR"))
203
+ end
204
+
205
+ @src_dir = @conf_hs["SRC_DIR"]
206
+ unless @src_dir
207
+ @mes.output_error("Can't get SRC_DIR in #{conf_path}")
208
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_SRC_DIR"))
209
+ end
210
+
211
+ @data_dir = @conf_hs["DATA_DIR"]
212
+ unless @data_dir
213
+ @mes.output_fatal("Cannot get DATA_DIR in #{conf_path}")
214
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_DATA_DIR"))
215
+ end
216
+
217
+ @work_dir = @conf_hs["WORK_DIR"]
218
+ unless @work_dir
219
+ @mes.output_fatal("Cannot get WORK_DIR in #{conf_path}")
220
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_WORK_DIR"))
221
+ end
222
+
223
+ @material_dir = @conf_hs["MATERIAL_DIR"]
224
+ unless @material_dir
225
+ @mes.output_fatal("Cannot get MATERIAL_DIR in #{conf_path}")
226
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_MATERIAL_DIR"))
227
+ end
228
+
229
+ @target_command_index = @conf_hs["TARGET_COMMAND_INDEX"].to_i
230
+ unless @target_command_index
231
+ @mes.output_fatal("Cannot get targetCommandIndex from #{conf_path}")
232
+ exit(@mes.ec("EXIT_CODE_CANNOT_CANNOT_GET_TARGET_COMMAND_INDEX"))
233
+ end
234
+
235
+ @subtarget_command_index = @conf_hs["SUBTARGET_COMMAND_INDEX"].to_i
236
+ unless @subtarget_command_index
237
+ @mes.output_fatal("Cannot get subTargetCommandIndex from #{conf_path}")
238
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_SUBTARGET_COMMAND_INDEX"))
239
+ end
240
+
241
+ @key_index = @conf_hs["KEY_INDEX"].to_i
242
+ unless @key_index
243
+ @mes.output_fatal("Cannot get keyIndex from #{conf_path}")
244
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_KEY_INDEX"))
245
+ end
246
+
247
+ @htmlfile_index = @conf_hs["HTMLFILE_INDEX"].to_i
248
+ unless @htmlfile_index
249
+ @mes.output_fatal("Cannot get htmlfileIndex from #{conf_path}")
250
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_HTMLFILE_INDEX"))
251
+ end
252
+
253
+ @alias_htmlfile_index = @conf_hs["ALIAS_HTMLFILE_INDEX"].to_i
254
+ unless @alias_htmlfile_index
255
+ @mes.output_fatal("Cannot get aliasHtmlfileIndex from #{conf_path}")
256
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_ALIAS_HTMLFILE_INDEX"))
257
+ end
258
+ end
259
+ # rubocop:enable Metrics/MethodLength, Style/GuardClause
260
+
261
+ #
262
+ # 指定ターゲットに属する全サブターゲットコマンド名を得る
263
+ # @param target_command [String] ターゲットコマンド名
264
+ # @return [Array] 指定ターゲットに属する全サブターゲットコマンド名の配列
265
+ def get_subtarget_commands(target_command)
266
+ if @commands[target_command]
267
+ if @commands[target_command]["subtargets"]
268
+ @commands[target_command]["subtargets"].map {|y| y }
269
+ else
270
+ []
271
+ end
272
+ else
273
+ []
274
+ end
275
+ end
276
+
277
+ #
278
+ # ターゲット名、サブターゲット名を指定してサブターゲットストラクト得る
279
+ # @param target_name [String] ターゲット名
280
+ # @param subtarget_name [String] サブターゲット名
281
+ # @return [Struct] 指定されたサブターゲットストラクト
282
+ def get_sub_target(target_name, subtarget_name)
283
+ @category[target_name].subTargets[subtarget_name]
284
+ end
285
+
286
+ #
287
+ # ターゲット名と出力HTMLファイルから、サブターゲットストラクトを得る
288
+ # @param target_name [String] ターゲット名
289
+ # @param htmlfpath [String] 出力HTMLファイルへのパス
290
+ # @return [Struct] 指定されたサブターゲットストラクト
291
+ def get_subtarget_by_htmlfile(target_name, htmlfpath)
292
+ @category[target_name].subTargetsByHtmlfile[htmlfpath]
293
+ end
294
+
295
+ #
296
+ # ターゲットコマンド名とサブターゲットコマンド名から、サブターゲットストラクトを得る
297
+ # @param target_command [String] ターゲットコマンド名
298
+ # @param subtarget_command [String] サブターゲットコマンド名
299
+ # @return [Array] 第0要素 ターゲットストラクト、第1要素 サブターゲットストラクト
300
+ def get_target_and_subtarget(target_command, subtarget_command)
301
+ current_target = nil
302
+ current_subtarget = nil
303
+ @mes.output_info("Env.get_target_and_subtarget")
304
+ @mes.output_info("target_command=#{target_command}")
305
+ @mes.output_info("subtarget_command=#{subtarget_command}")
306
+ if @commands[target_command]
307
+ current_target = @commands[target_command]["target"]
308
+ if @commands[target_command]["subtargets"]
309
+ current_subtarget = @commands[target_command]["subtargets"][subtarget_command]
310
+ else
311
+ @mes.output_info("@commands[target_command]['subtargets']")
312
+ end
313
+ else
314
+ @mes.output_info("@commands[target_command]=nil")
315
+ @mes.output_error("Not specified legal target command")
316
+ exit(@mes.ec("EXIT_CODE_NOT_SPECIFIED_LEGAL_TARGET_COMMAND"))
317
+ end
318
+ [current_target, current_subtarget]
319
+ end
320
+
321
+ #
322
+ # 変数展開 イコールの右辺にある変数名をhash,subhsのどちらかに含まれる、該当変数名をキーとした場合の値に置き換える
323
+ # @param var [String] 変数の値
324
+ # @param hash [Hash] ハッシュ
325
+ # @param subhs [Hash] 第2ハッシュ
326
+ # @return [Array] 展開された変数の値
327
+ def expand_variable(var, hash, subhs={})
328
+ if (m = /(\${([^}]+)})/.match(var))
329
+ pattern = m[1]
330
+ var_name = m[2]
331
+ @mes.output_debug("var_name=#{var_name}")
332
+ expand = hash[var_name]
333
+ expand ||= subhs[var_name]
334
+ @mes.output_debug("expand=#{expand}")
335
+ expand ||= ENV[var_name]
336
+ if expand
337
+ var[pattern] = expand
338
+ expand_variable(var, hash, subhs) if var.index("$")
339
+ end
340
+ end
341
+ var
342
+ end
343
+
344
+ #
345
+ # 構成ファイルを(変数展開しつつ)ハッシュに変換する
346
+ # @param conf_fname [String] 構成ファイル名
347
+ # @param hash [Hash] ハッシュ(構成ファイルの内容が追加される)
348
+ # @param subhs [Hash] 第2ハッシュ
349
+ def setup_from_conf(conf_fname, hash, subhs={})
350
+ @mes.exc_file_gets(conf_fname) do
351
+ File.open(conf_fname) do |f|
352
+ while (l = f.gets)
353
+ l = l.chomp
354
+ next if /^\s*#/ =~ l
355
+ next if /^\s*$/ =~ l
356
+ if (m = /\s*([^=]+)=([^=]+)\s*$/.match(l))
357
+ hash[m[1]] = m[2]
358
+ end
359
+ end
360
+ end
361
+ end
362
+
363
+ keys = hash.keys
364
+ keys.each do |key|
365
+ hash[key] = expand_variable(hash[key], hash, subhs)
366
+ end
367
+ end
368
+
369
+ #
370
+ # エイリアス指定をディレクトリ指定と、ファイル名指定に分解する
371
+ # @param array [Array] カテゴリ別設定ファイルでのパート指定のフィールドの配列
372
+ # @return [Array] 第0要素:エイリアスディレクトリ指定、第1要素:エイリアスファイル名指定
373
+ def normalize_alias_htmlpath(array)
374
+ if array.size >= (@alias_htmlfile_index + 1)
375
+ alias_htmlfname = array[@alias_htmlfile_index]
376
+ alias_dir = File.dirname(alias_htmlfname)
377
+ alias_basename = File.basename(alias_htmlfname, ".html")
378
+ if alias_dir == "."
379
+ alias_html_dir = ""
380
+ end
381
+ alias_htmlfname_x = [alias_basename, "html"].join(".")
382
+ else
383
+ alias_html_dir = ""
384
+ alias_htmlfname_x = ""
385
+ end
386
+
387
+ [alias_html_dir, alias_htmlfname_x]
388
+ end
389
+
390
+ #
391
+ # HTMLファイル名指定からディレクトリ指定と、ファイル名指定、サブターゲット名、Makrdownファイル名を得る
392
+ # @param htmlfname [String] HTMLファイル名指定
393
+ # @return [Array] 第0要素:サブターゲット名、第1要素:HTMLファイル名指定、第2要素:HTMLディレクトリ指定、第3要素:Markdownファイル名指定
394
+ def normalize_htmlpath(htmlfname)
395
+ dir = File.dirname(htmlfname)
396
+ basename = File.basename(htmlfname)
397
+ basename_no_ext = File.basename(htmlfname, ".html")
398
+ if dir == "."
399
+ subtarget_name = basename_no_ext
400
+ htmldir = ""
401
+ else
402
+ subtarget_name = File.join(dir, basename_no_ext)
403
+ htmldir = dir
404
+ end
405
+ htmlfname_x = basename
406
+ mdfname = [basename_no_ext, "md"].join(".")
407
+
408
+ [subtarget_name, htmlfname_x, htmldir, mdfname]
409
+ end
410
+
411
+ #
412
+ # 名前引きカテゴリ別構成、コマンド別構成の設定
413
+ # @param target_command [String] ターゲットコマンド名
414
+ # @param subtarget_command [String] サブターゲットコマンド名
415
+ # @param stds [String] サブターゲットストラクト
416
+ # @param target [String] ターゲット名
417
+ # @param subtarget [String] サブターゲット名
418
+ # @param htmlfname [String] HTMLファイル名
419
+ def setup_category_oneline_x(target_command, subtarget_command, stds, target, subtarget, htmlfname)
420
+ @category[target].subTargets[subtarget] = stds
421
+ @category[target].subTargetsByHtmlfile[htmlfname] = stds
422
+
423
+ if @commands[target_command]
424
+ if @commands[target_command]["subtargets"]
425
+ @commands[target_command]["subtargets"][subtarget_command] = stds
426
+ else
427
+ @mes.output_error("Not specified legal target command")
428
+ exit(@mes.ec("EXIT_CODE_NOT_SPECIFIED_LEGAL_TARGET_COMMAND"))
429
+ end
430
+ else
431
+ @mes.output_error("Not specified legal target command")
432
+ exit(@mes.ec("EXIT_CODE_NOT_SPECIFIED_LEGAL_TARGET_COMMAND"))
433
+ end
434
+ end
435
+
436
+ #
437
+ # 名前引きカテゴリ別構成、コマンド別構成の設定
438
+ # @param fields [Array] カテゴリ別設定ファイルでのパート指定のフィールドの配列
439
+ # @param target_name [String] ターゲット名
440
+ # @param target_command [String] ターゲットコマンド名
441
+ # @param subtarget_command [String] サブターゲットコマンド名
442
+ # @param category_x [String] 名前引きカテゴリ別構成
443
+ # @return [Array] 第0要素: サブターゲット名 第1要素: サブターゲットストラクト 第2要素: HTMLファイル名
444
+ def setup_category_oneline_sub(fields, target_name, target_command, subtarget_command, category_x)
445
+ if fields.size >= (@htmlfile_index + 1)
446
+ htmlfname = fields[@htmlfile_index]
447
+ else
448
+ htmlfname = nil
449
+ end
450
+ alias_htmldir, alias_htmlfname_x = normalize_alias_htmlpath(fields)
451
+
452
+ @mes.output_debug("htmlfname=#{htmlfname}")
453
+ @mes.output_debug("alias_htmlfname_x=#{alias_htmlfname_x}")
454
+
455
+ misc = fields
456
+ target_dir = File.join(@src_dir, target_name)
457
+
458
+ unless @category[target_name]
459
+ tds = @target_struct.new(target_name, target_dir, nil, nil, nil, nil, nil, nil, nil, nil, target_command, nil, nil, [])
460
+ @category[target_name] = @category_struct.new(tds, misc, {}, {})
461
+ end
462
+ unless @commands[target_command]
463
+ @commands[target_command] ||= { "target" => @category[target_name].target, "subtargets" => {}, "category" => @category[target_name] }
464
+ end
465
+ except = htmlfname.index("/") ? true : false
466
+
467
+ subtarget, htmlfname_x, htmldir, mdfname = normalize_htmlpath(htmlfname)
468
+ subtarget_name = subtarget.dup
469
+
470
+ category_x[:category][target_name][subtarget_name] = fields
471
+
472
+ subtarget_dir = File.join(target_dir, subtarget_name)
473
+
474
+ subtarget_data_dir = File.join(subtarget_dir, @data_dir)
475
+ subtarget_work_dir = File.join(subtarget_dir, @work_dir)
476
+ subtarget_material_dir = File.join(subtarget_dir, @material_dir)
477
+
478
+ stds = @target_struct.new(subtarget_name, subtarget_dir, subtarget_data_dir, subtarget_work_dir, subtarget_material_dir, htmldir, htmlfname_x, mdfname, nil, except, subtarget_command, alias_htmldir, alias_htmlfname_x, [])
479
+ [stds, subtarget, htmlfname]
480
+ end
481
+
482
+ #
483
+ # カテゴリ別設定ファイルでのパート指定単位での名前引きカテゴリ別構成、コマンド別構成の設定
484
+ # @param fields [Array] カテゴリ別設定ファイルでのパート指定のフィールドの配列
485
+ # @param category_x [String] 名前引きカテゴリ別構成
486
+ # @param file_path [String] カテゴリ別設定ファイルへのパス
487
+ def setup_category_oneline(fields, category_x, file_path)
488
+ category_x[:array] << fields
489
+ category_x[:category] ||= {}
490
+
491
+ target_command = fields[@target_command_index]
492
+ subtarget_command = fields[@subtarget_command_index]
493
+ target_name = fields[@key_index]
494
+ if target_name.strip.empty?
495
+ @mes.output_fatal("Cannot get target from #{file_path}")
496
+ exit(@mes.ec("EXIT_CODE_CANNOT_GET_TARGET"))
497
+ end
498
+
499
+ category_x[:category][target_name] ||= {}
500
+
501
+ stds, subtarget, htmlfname = setup_category_oneline_sub(fields, target_name, target_command, subtarget_command, category_x)
502
+
503
+ setup_category_oneline_x(target_command, subtarget_command, stds, target_name, subtarget, htmlfname)
504
+ end
505
+
506
+ #
507
+ # 名前引きカテゴリ別構成の設定
508
+ # @param file_path [String] カテゴリ別設定ファイルへのパス
509
+ def setup_category(file_path)
510
+ category_x = { array: [], category: {} }
511
+ @mes.exc_file_gets(file_path) do
512
+ f = File.open(file_path)
513
+ while (l = f.gets)
514
+ l.chomp!
515
+ next if /^#/.match?(l)
516
+ next if l.strip.empty?
517
+ array = l.split("\t")
518
+ size = array.size
519
+ if @target_command_index >= size
520
+ @mes.output_fatal("Invalid targetCommandIndex(=#{@target_command_index})")
521
+ exit(@mes.ec("EXIT_CODE_INVALID_INDEX"))
522
+ end
523
+ if @subtarget_command_index >= size
524
+ @mes.output_fatal("Invalid subTargetCommandIndex(=#{@subtarget_command_index})")
525
+ exit(@mes.ec("EXIT_CODE_INVALID_INDEX"))
526
+ end
527
+ if @htmlfile_index >= size
528
+ @mes.output_fatal("Invalid htmlfileIndex(=#{@htmlfile_index})")
529
+ exit(@mes.ec("EXIT_CODE_INVALID_INDEX"))
530
+ end
531
+ setup_category_oneline(array, category_x, file_path)
532
+ end
533
+ f.close
534
+ end
535
+ category_x
536
+ end
537
+
538
+ #
539
+ # カテゴリ別設定ファイルの内容をカテゴリストラクトに反映する
540
+ # @param category_struct [Struct] カテゴリストラクト
541
+ # @param obj [Hash] カテゴリ別設定ファイル(YAML形式)を変換したハッシュ
542
+ def setup_target_config(category_struct, obj)
543
+ category_struct.subTargets.each do |_k, v|
544
+ v.filedir = @filedir.new(File.join(@root_output_dir, v.htmldir, v.htmlfile).to_s,
545
+ File.join(v.materialDir, v.htmlfile).to_s,
546
+ File.join(v.materialDir, "0.html").to_s,
547
+ File.join(v.materialDir, "2.html").to_s,
548
+ File.join(v.dataDir, v.mdfile).to_s,
549
+ File.join(v.workDir, v.mdfile).to_s,
550
+ File.join(@root_output_dir, v.htmldir, v.mdfile).to_s,
551
+ v.dataDir.to_s)
552
+ subtarget_name = v.name
553
+
554
+ next unless obj && obj[subtarget_name]
555
+
556
+ obj[subtarget_name].each do |x|
557
+ name, template, misc = x.split(",")
558
+ macroname = name
559
+ x2 = name.dup
560
+ x2[OUTPUT_DIR] = "" if x2.index(OUTPUT_DIR)
561
+
562
+ outputfname = File.join(v.workDir, %Q(#{x2}.md))
563
+
564
+ src_subtarget_name = nil
565
+ if template == INCLUDE_INDICATOR
566
+ kind = :INCLUDE
567
+ datafname = File.join(misc, %Q(#{x2}.md))
568
+ src_subtarget_name = name
569
+ else
570
+ kind = :NORMAL
571
+ datafname = File.join(v.dataDir, %Q(#{x2}.yml))
572
+ end
573
+ v.templates << @template_struct.new(datafname, template, outputfname, macroname, kind, src_subtarget_name)
574
+ end
575
+ end
576
+ end
577
+
578
+ #
579
+ # 全カテゴリに対して、対応するカテゴリ別設定ファイルの内容を反映する
580
+ #
581
+ def setup_config
582
+ @category.each do |name, category_struct|
583
+ target = name
584
+ targetconf_yamlfile = %Q(#{@category_conf_prefix}#{target}.yml)
585
+ targetconf_yamlpath = File.join(@absolute_path_root_conf, targetconf_yamlfile)
586
+ unless File.exist?(targetconf_yamlpath)
587
+ @mes.output_error("Can't find targetconf_yamlpath(=#{targetconf_yamlpath})")
588
+ exit(@mes.ec("EXIT_CODE_CANNOT_FIND_TARGETCONFYAMLPATH"))
589
+ end
590
+ obj = Filex::Filex.check_and_load_yamlfile(targetconf_yamlpath, @mes)
591
+ setup_target_config(category_struct, obj)
592
+ end
593
+ end
594
+
595
+ def get_filepath(path)
596
+ if path
597
+ @mes.output_debug("0 path=#{path}")
598
+ if File.exist?(path)
599
+ abs_path = File.expand_path(path)
600
+ @mes.output_debug("1 absPath=#{abs_path}")
601
+ else
602
+ abs_path = nil
603
+ end
604
+ else
605
+ abs_path = nil
606
+ @mes.output_debug("4 absPath=#{abs_path}")
607
+ end
608
+ abs_path
609
+ end
610
+
611
+ def make_zlist
612
+ @commands.map {|t_name, t_hash| t_hash["subtargets"].map {|_, s_hash| %Q(-t #{t_name} -s #{s_hash['command']}) } }.flatten
613
+ end
614
+
615
+ def make_anchar_tag(hash)
616
+ %Q(<li><a href="#{hash['htmlfile']}">#{hash['htmlfile']}</a></li>)
617
+ end
618
+
619
+ def make_html_first
620
+ <<~_HTML_HEAD
621
+ <html>
622
+ <head>
623
+ </head>
624
+ <body>
625
+ <ul>
626
+ _HTML_HEAD
627
+ end
628
+
629
+ def make_html_last
630
+ <<~_HTML_BODY_TAIL
631
+ </ul>
632
+ </body>
633
+ </html>
634
+ _HTML_BODY_TAIL
635
+ end
636
+
637
+ def make_zindex_html
638
+ fname = File.join(@absolutepath_root, @root_output_dir, ZINDEX_HTML_FILE)
639
+ @mes.exc_file_write(fname) do
640
+ f = File.open(fname, "w")
641
+ f.puts(make_html_first)
642
+ anchars = @commands.map {|_, t_hash| t_hash["subtargets"].map {|_, s_hash| make_anchar_tag(s_hash) } }
643
+ f.puts(anchars.flatten.join("\n"))
644
+ f.puts(make_html_last)
645
+ f.close
646
+ end
647
+ end
648
+ end
649
+ end