md2site 0.1.2 → 0.1.4
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -19
- data/Gemfile +1 -1
- data/Gemfile.lock +21 -28
- data/bin/md2site +26 -31
- data/data/_x/diff.txt +337 -0
- data/data/_x/list.txt +495 -0
- data/data/_x/list2.txt +495 -0
- data/data/_x/list3.txt +415 -0
- data/data/_x/list4.txt +415 -0
- data/data/_x/list5.txt +392 -0
- data/data/_x/list6.txt +298 -0
- data/data/_x/list7.txt +201 -0
- data/data/_x/list8.txt +199 -0
- data/data/_x/outer_url.txt +94 -0
- data/data/_x/s.txt +140 -0
- data/data/conf/conf.sh +0 -2
- data/data/testdata/{conf-blog.yml → conf/conf-blog.yml} +0 -0
- data/data/testdata/{conf-download.yml → conf/conf-download.yml} +0 -0
- data/data/testdata/{conf-link.yml → conf/conf-link.yml} +0 -0
- data/data/testdata/{conf-profile.yml → conf/conf-profile.yml} +0 -0
- data/data/testdata/{conf-top.yml → conf/conf-top.yml} +0 -0
- data/data/testdata/{site.tsv → conf/site.tsv} +0 -0
- data/data/testdata0/{conf-appliction.yml → conf/conf-appliction.yml} +0 -0
- data/data/testdata0/{conf-attempt.yml → conf/conf-attempt.yml} +16 -16
- data/data/testdata0/conf/conf-autosar.yml +11 -0
- data/data/testdata0/{conf-community.yml → conf/conf-community.yml} +0 -0
- data/data/testdata0/{conf-document.yml → conf/conf-document.yml} +0 -0
- data/data/testdata0/{conf-download.yml → conf/conf-download.yml} +0 -0
- data/data/testdata0/{conf-edu.yml → conf/conf-edu.yml} +18 -19
- data/data/testdata0/{conf-etc.yml → conf/conf-etc.yml} +0 -0
- data/data/testdata0/{conf-members.yml → conf/conf-members.yml} +0 -0
- data/data/testdata0/{conf-product.yml → conf/conf-product.yml} +9 -9
- data/data/testdata0/{conf-project.yml → conf/conf-project.yml} +2 -2
- data/data/testdata0/conf/conf-rtk.yml +25 -0
- data/data/testdata0/conf/conf-sample.yml +5 -0
- data/data/testdata0/{conf-top.yml → conf/conf-top.yml} +0 -0
- data/data/testdata0/conf/conf.sh +32 -0
- data/data/testdata0/{setting.yml → conf/setting.yml} +11 -0
- data/data/testdata0/{site.tsv → conf/site.tsv} +109 -2
- data/data/testdata0/conf/status.txt +6 -0
- data/lib/md2site/env.rb +248 -276
- data/lib/md2site/envcheck.rb +186 -0
- data/lib/md2site/htmlutils0.rb +64 -2
- data/lib/md2site/info.rb +12 -0
- data/lib/md2site/init.rb +61 -5
- data/lib/md2site/listfile.rb +16 -0
- data/lib/md2site/make.rb +92 -31
- data/lib/md2site/nkfguess.rb +8 -0
- data/lib/md2site/setup.rb +104 -28
- data/lib/md2site/statusfile.rb +98 -6
- data/lib/md2site/testdata.rb +43 -3
- data/lib/md2site/testx.rb +28 -1
- data/lib/md2site/version.rb +1 -1
- data/lib/md2site.rb +93 -26
- data/md2site.gemspec +5 -6
- metadata +77 -76
- data/data/testdata0/conf-autosar.yml +0 -11
- data/data/testdata0/conf-rtk.yml +0 -25
data/lib/md2site/env.rb
CHANGED
@@ -7,18 +7,31 @@ module Md2site
|
|
7
7
|
require "fileutils"
|
8
8
|
require "filex"
|
9
9
|
|
10
|
+
# 構成ハッシュ
|
11
|
+
#
|
12
|
+
# @return [Hash] 構成ファイルの変数名をキー、変数の値を値とするハッシュ
|
10
13
|
attr_reader :conf_hs
|
14
|
+
# ターゲットコマンド名引きコマンドストラクトハッシュ
|
15
|
+
#
|
16
|
+
# @return [Hash] ターゲットコマンド名をキー、コマンドストラクトを値とするハッシュ
|
11
17
|
attr_reader :commands
|
12
|
-
|
13
|
-
|
18
|
+
# ターゲット名引きカテゴリ・ターゲットストラクトハッシュ
|
19
|
+
#
|
20
|
+
# @return [Hash] ターゲット名をキーとして、カテゴリ・ターゲットストラクトを値とするハッシュ
|
21
|
+
attr_reader :category_target
|
22
|
+
# @return [Integer] HTMLファイル名のインデックス
|
14
23
|
attr_reader :htmlfile_index
|
24
|
+
# @return [Integer] エイリアスHTMLファイル名のインデックス
|
15
25
|
attr_reader :alias_htmlfile_index
|
26
|
+
# @return [String] プロジェクトルートディレクトリの絶対パス
|
16
27
|
attr_reader :absolutepath_root
|
28
|
+
# @return [String] サイト固有設定ファイルの絶対パス
|
17
29
|
attr_reader :absolutepath_root_settingfile
|
18
30
|
|
19
31
|
#
|
20
32
|
# 初期化
|
21
|
-
#
|
33
|
+
#
|
34
|
+
# @param conf_path [String] 構成ファイルのパス
|
22
35
|
# @param mes [Messagex] Messagexクラスのインスタンス
|
23
36
|
# @param verbose [Boolean] FileUtilsクラスのメソッドのverbose引数に与える値
|
24
37
|
def initialize(conf_path, mes, verbose)
|
@@ -26,30 +39,66 @@ module Md2site
|
|
26
39
|
@verbose = verbose
|
27
40
|
register_exit_codes
|
28
41
|
|
29
|
-
@
|
42
|
+
@envcheck = EnvCheck.new(mes, conf_path)
|
43
|
+
|
44
|
+
# カテゴリ・ターゲットストラクト定義
|
45
|
+
#
|
46
|
+
# カテゴリに含まれるターゲットとサブターゲットを関連付ける
|
47
|
+
# カテゴリはターゲットをまとめるのが役割である。。
|
48
|
+
# ターゲット名は全カテゴリにおいて一意でなければならない。
|
49
|
+
@category_target_struct = Struct.new(:target, :misc, :subTargets, :subTargetsByHtmlfile)
|
50
|
+
|
51
|
+
# ターゲットストラクト定義
|
52
|
+
#
|
53
|
+
# ターゲットはサブターゲットをまとめるのが役割である。
|
54
|
+
# サブターゲットは1個のHTMLを生成するのが役割である。
|
55
|
+
# ターゲットストラクト定義はターゲット向けのものとサブターゲット向けのものとの両方を含んでいて、
|
56
|
+
# ターゲット、サブターゲットのどちらに対しても用いる。
|
57
|
+
#
|
30
58
|
@target_struct = Struct.new(:name, :dir, :dataDir, :workDir, :materialDir, :htmldir, :htmlfile, :mdfile, :filedir, :except, :command, :aliashtmldir, :aliashtmlfile, :templates)
|
59
|
+
|
60
|
+
# templateストラクト定義
|
61
|
+
#
|
62
|
+
# YAML形式ファイルまたはMakrdown型式ファイルから、Markdown形式ファイルを生成するために必要な情報を持つ
|
31
63
|
@template_struct = Struct.new(:datafname, :templatefname, :outputfname, :macroname, :kind, :src_subtarget_name)
|
32
|
-
|
64
|
+
|
65
|
+
# ファイルディレクトリストラクト定義
|
66
|
+
#
|
67
|
+
# Makrdown型式ファイルから、HTML形式ファイルを生成するために必要な情報を持つ
|
68
|
+
@filedir_struct = Struct.new(:html_output, :html_input, :partAhtml, :partChtml, :input_md, :output_md, :root_output_md, :data_dir)
|
69
|
+
|
70
|
+
# コマンドストラクト定義
|
71
|
+
#
|
72
|
+
# ターゲットコマンド名、サブターゲットコマンド名からターゲット、サブターゲットを得るための情報を持つ
|
73
|
+
@command_struct = Struct.new(:target, :subtargets)
|
74
|
+
|
75
|
+
# ターゲットコマンド名引きコマンドストラクトハッシュ
|
33
76
|
@commands = {}
|
34
|
-
|
77
|
+
|
78
|
+
# ターゲット名引きカテゴリ・ターゲットストラクトハッシュ
|
79
|
+
@category_target = {}
|
80
|
+
|
81
|
+
# 構成ファイル中の変数名をキー都市、変数値を値とする構成ハッシュ
|
35
82
|
@conf_hs = {}
|
36
83
|
|
37
|
-
check_conf_path
|
84
|
+
@envcheck.check_conf_path
|
85
|
+
@absolutepath_root = File.dirname(File.dirname(File.absolute_path(conf_path)))
|
86
|
+
@conf_hs["ABSOLUTE_PATH_ROOT"] = @absolutepath_root
|
38
87
|
setup_from_conf(conf_path, @conf_hs)
|
39
88
|
|
40
|
-
check_conf_hs_for_attribute
|
41
|
-
check_conf_hs_and_set
|
42
|
-
check_conf_hs
|
89
|
+
check_conf_hs_for_attribute
|
90
|
+
check_conf_hs_and_set
|
91
|
+
check_conf_hs
|
43
92
|
|
44
|
-
|
93
|
+
setup_category(@sitefile_path)
|
45
94
|
setup_config
|
46
95
|
end
|
47
96
|
|
48
97
|
#
|
49
|
-
#
|
98
|
+
# 終了ステータスの登録
|
50
99
|
#
|
51
|
-
#
|
52
|
-
def register_exit_codes
|
100
|
+
# @return [void]
|
101
|
+
def register_exit_codes # rubocop:disable Metrics/MethodLength
|
53
102
|
@mes.add_exitcode("EXIT_CODE_CANNOT_FIND_CONFFILE")
|
54
103
|
@mes.add_exitcode("EXIT_CODE_NOT_SPECIFIED_CONFFILE")
|
55
104
|
@mes.add_exitcode("EXIT_CODE_CANNOT_GET_ABSOLUTE_PATH_ROOT_CONF")
|
@@ -83,189 +132,40 @@ module Md2site
|
|
83
132
|
@mes.add_exitcode("EXIT_CODE_CANNOT_FIND_TARGETCONFYAMLPATH")
|
84
133
|
@mes.add_exitcode("EXIT_CODE_NOT_SPECIFIED_LEGAL_TARGET_COMMAND")
|
85
134
|
end
|
86
|
-
# rubocop:enable Metrics/MethodLength
|
87
135
|
|
88
136
|
#
|
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
|
-
|
137
|
+
# Envクラスのattributeとして有効な値が構成ファイル中に指定されているか調べる(無効であればexitする)
|
105
138
|
#
|
106
|
-
#
|
107
|
-
|
108
|
-
|
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
|
139
|
+
# @return [void]
|
140
|
+
def check_conf_hs_for_attribute
|
141
|
+
@absolute_path_root_conf, @absolutepath_root_settingfile = @envcheck.check_conf_hs_for_attribute(@conf_hs)
|
134
142
|
end
|
135
143
|
|
136
144
|
#
|
137
|
-
#
|
138
|
-
# @param conf_path [String] 構成ファイルへのパス
|
145
|
+
# 構成ファイルから変換したハッシュに有効な値が指定されているか調べる(無効であればexitする)
|
139
146
|
#
|
140
|
-
#
|
141
|
-
def check_conf_hs
|
142
|
-
|
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
|
147
|
+
# @return [void]
|
148
|
+
def check_conf_hs
|
149
|
+
@sitefile_path = @envcheck.check_conf_hs(@conf_hs, @absolutepath_root, @root_output_dir)
|
185
150
|
end
|
186
|
-
# rubocop:enable Metrics/MethodLength, Style/GuardClause
|
187
151
|
|
188
152
|
#
|
189
|
-
#
|
190
|
-
#
|
191
|
-
#
|
192
|
-
def check_conf_hs_and_set
|
193
|
-
@category_conf_prefix = @conf_hs
|
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
|
153
|
+
# 構成ファイルから変換したハッシュに指定されている値が有効であれば、インスタンス変数で参照できるようにする(無効であればexitする)
|
154
|
+
#
|
155
|
+
# @return [void]
|
156
|
+
def check_conf_hs_and_set # rubocop:disable Metrics/MethodLength
|
157
|
+
@category_conf_prefix, @root_output_dir, @src_dir, @data_dir, @work_dir, @material_dir, @target_command_index, @subtarget_command_index, @key_index, @htmlfile_index, @alias_htmlfile_index = @envcheck.check_conf_hs_and_set(@conf_hs)
|
258
158
|
end
|
259
|
-
|
260
|
-
|
159
|
+
|
261
160
|
#
|
262
161
|
# 指定ターゲットに属する全サブターゲットコマンド名を得る
|
162
|
+
#
|
263
163
|
# @param target_command [String] ターゲットコマンド名
|
264
|
-
# @return [Array] 指定ターゲットに属する全サブターゲットコマンド名の配列
|
164
|
+
# @return [Array<Struct>] 指定ターゲットに属する全サブターゲットコマンド名の配列
|
265
165
|
def get_subtarget_commands(target_command)
|
266
166
|
if @commands[target_command]
|
267
|
-
if @commands[target_command][
|
268
|
-
@commands[target_command][
|
167
|
+
if @commands[target_command][:subtargets]
|
168
|
+
@commands[target_command][:subtargets].keys
|
269
169
|
else
|
270
170
|
[]
|
271
171
|
end
|
@@ -276,24 +176,27 @@ module Md2site
|
|
276
176
|
|
277
177
|
#
|
278
178
|
# ターゲット名、サブターゲット名を指定してサブターゲットストラクト得る
|
179
|
+
#
|
279
180
|
# @param target_name [String] ターゲット名
|
280
181
|
# @param subtarget_name [String] サブターゲット名
|
281
182
|
# @return [Struct] 指定されたサブターゲットストラクト
|
282
183
|
def get_sub_target(target_name, subtarget_name)
|
283
|
-
@
|
184
|
+
@category_target[target_name].subTargets[subtarget_name]
|
284
185
|
end
|
285
186
|
|
286
187
|
#
|
287
188
|
# ターゲット名と出力HTMLファイルから、サブターゲットストラクトを得る
|
189
|
+
#
|
288
190
|
# @param target_name [String] ターゲット名
|
289
191
|
# @param htmlfpath [String] 出力HTMLファイルへのパス
|
290
192
|
# @return [Struct] 指定されたサブターゲットストラクト
|
291
193
|
def get_subtarget_by_htmlfile(target_name, htmlfpath)
|
292
|
-
@
|
194
|
+
@category_target[target_name].subTargetsByHtmlfile[htmlfpath]
|
293
195
|
end
|
294
196
|
|
295
197
|
#
|
296
198
|
# ターゲットコマンド名とサブターゲットコマンド名から、サブターゲットストラクトを得る
|
199
|
+
#
|
297
200
|
# @param target_command [String] ターゲットコマンド名
|
298
201
|
# @param subtarget_command [String] サブターゲットコマンド名
|
299
202
|
# @return [Array] 第0要素 ターゲットストラクト、第1要素 サブターゲットストラクト
|
@@ -304,28 +207,30 @@ module Md2site
|
|
304
207
|
@mes.output_info("target_command=#{target_command}")
|
305
208
|
@mes.output_info("subtarget_command=#{subtarget_command}")
|
306
209
|
if @commands[target_command]
|
307
|
-
current_target = @commands[target_command][
|
308
|
-
if @commands[target_command][
|
309
|
-
current_subtarget = @commands[target_command][
|
210
|
+
current_target = @commands[target_command][:target]
|
211
|
+
if @commands[target_command][:subtargets]
|
212
|
+
current_subtarget = @commands[target_command][:subtargets][subtarget_command]
|
310
213
|
else
|
311
|
-
@mes.output_info("@commands[target_command][
|
214
|
+
@mes.output_info("@commands[target_command][:subtargets]")
|
312
215
|
end
|
313
216
|
else
|
314
217
|
@mes.output_info("@commands[target_command]=nil")
|
315
|
-
@mes.output_error("Not specified legal target command")
|
218
|
+
@mes.output_error("Not specified legal target command 1")
|
316
219
|
exit(@mes.ec("EXIT_CODE_NOT_SPECIFIED_LEGAL_TARGET_COMMAND"))
|
317
220
|
end
|
318
221
|
[current_target, current_subtarget]
|
319
222
|
end
|
320
223
|
|
321
224
|
#
|
322
|
-
# 変数展開 イコールの右辺にある変数名をhash,subhs
|
323
|
-
#
|
324
|
-
# @param
|
325
|
-
# @param
|
326
|
-
# @
|
327
|
-
|
328
|
-
|
225
|
+
# 変数展開 イコールの右辺にある変数名をhash,subhsのどちらかに含まれる、該当変数名をキーとしたハッシュの値に置き換える
|
226
|
+
#
|
227
|
+
# @param value [String] 展開元の変数の値
|
228
|
+
# @param hash [Hash] 置換用ハッシュ
|
229
|
+
# @param subhs [Hash] 第2置換用ハッシュ
|
230
|
+
# @return [String] 展開された変数の値
|
231
|
+
def expand_variable(value, hash, subhs={})
|
232
|
+
@mes.output_debug("value=#{value}")
|
233
|
+
if (m = /(\${([^}]+)})/.match(value))
|
329
234
|
pattern = m[1]
|
330
235
|
var_name = m[2]
|
331
236
|
@mes.output_debug("var_name=#{var_name}")
|
@@ -334,18 +239,20 @@ module Md2site
|
|
334
239
|
@mes.output_debug("expand=#{expand}")
|
335
240
|
expand ||= ENV[var_name]
|
336
241
|
if expand
|
337
|
-
|
338
|
-
expand_variable(
|
242
|
+
value[pattern] = expand
|
243
|
+
expand_variable(value, hash, subhs) if value.index("$")
|
339
244
|
end
|
340
245
|
end
|
341
|
-
|
246
|
+
value
|
342
247
|
end
|
343
248
|
|
344
249
|
#
|
345
250
|
# 構成ファイルを(変数展開しつつ)ハッシュに変換する
|
251
|
+
#
|
346
252
|
# @param conf_fname [String] 構成ファイル名
|
347
253
|
# @param hash [Hash] ハッシュ(構成ファイルの内容が追加される)
|
348
254
|
# @param subhs [Hash] 第2ハッシュ
|
255
|
+
# @return [void]
|
349
256
|
def setup_from_conf(conf_fname, hash, subhs={})
|
350
257
|
@mes.exc_file_gets(conf_fname) do
|
351
258
|
File.open(conf_fname) do |f|
|
@@ -354,7 +261,7 @@ module Md2site
|
|
354
261
|
next if /^\s*#/ =~ l
|
355
262
|
next if /^\s*$/ =~ l
|
356
263
|
if (m = /\s*([^=]+)=([^=]+)\s*$/.match(l))
|
357
|
-
hash[m[1]]
|
264
|
+
hash[m[1]] ||= m[2]
|
358
265
|
end
|
359
266
|
end
|
360
267
|
end
|
@@ -368,7 +275,8 @@ module Md2site
|
|
368
275
|
|
369
276
|
#
|
370
277
|
# エイリアス指定をディレクトリ指定と、ファイル名指定に分解する
|
371
|
-
#
|
278
|
+
#
|
279
|
+
# @param array [Array] カテゴリ別設定ファイルでのサブコンポーネント指定のフィールドの配列
|
372
280
|
# @return [Array] 第0要素:エイリアスディレクトリ指定、第1要素:エイリアスファイル名指定
|
373
281
|
def normalize_alias_htmlpath(array)
|
374
282
|
if array.size >= (@alias_htmlfile_index + 1)
|
@@ -389,6 +297,7 @@ module Md2site
|
|
389
297
|
|
390
298
|
#
|
391
299
|
# HTMLファイル名指定からディレクトリ指定と、ファイル名指定、サブターゲット名、Makrdownファイル名を得る
|
300
|
+
#
|
392
301
|
# @param htmlfname [String] HTMLファイル名指定
|
393
302
|
# @return [Array] 第0要素:サブターゲット名、第1要素:HTMLファイル名指定、第2要素:HTMLディレクトリ指定、第3要素:Markdownファイル名指定
|
394
303
|
def normalize_htmlpath(htmlfname)
|
@@ -409,39 +318,45 @@ module Md2site
|
|
409
318
|
end
|
410
319
|
|
411
320
|
#
|
412
|
-
#
|
321
|
+
# ターゲット名引きカテゴリ・ターゲットストラクトハッシュ、ターゲットコマンド名引きコマンドストラクトハッシュの設定
|
322
|
+
# (適切なコマンド名でなければexitする)
|
323
|
+
#
|
413
324
|
# @param target_command [String] ターゲットコマンド名
|
414
325
|
# @param subtarget_command [String] サブターゲットコマンド名
|
415
326
|
# @param stds [String] サブターゲットストラクト
|
416
327
|
# @param target [String] ターゲット名
|
417
328
|
# @param subtarget [String] サブターゲット名
|
418
329
|
# @param htmlfname [String] HTMLファイル名
|
330
|
+
# @return [void]
|
419
331
|
def setup_category_oneline_x(target_command, subtarget_command, stds, target, subtarget, htmlfname)
|
420
|
-
|
421
|
-
@
|
332
|
+
# ターゲット名引きカテゴリ・ターゲットストラクトハッシュに、ターゲット名、サブターゲット名に対応するサブターゲットストラクトを設定
|
333
|
+
@category_target[target].subTargets[subtarget] = stds
|
334
|
+
# ターゲット名引きカテゴリ・ターゲットハッシュに、ターゲット名、HTMLファイル名に対応するサブターゲットストラクトを設定
|
335
|
+
@category_target[target].subTargetsByHtmlfile[htmlfname] = stds
|
422
336
|
|
337
|
+
# ターゲットコマンド名引きコマンドストラクトハッシュに、ターゲットコマンド名、サブターゲットコマンド名に対応するサブターゲットストラクトを設定
|
423
338
|
if @commands[target_command]
|
424
|
-
if @commands[target_command][
|
425
|
-
@commands[target_command][
|
339
|
+
if @commands[target_command][:subtargets]
|
340
|
+
@commands[target_command][:subtargets][subtarget_command] = stds
|
426
341
|
else
|
427
|
-
@mes.output_error("Not specified legal target command")
|
342
|
+
@mes.output_error("Not specified legal target command 2")
|
428
343
|
exit(@mes.ec("EXIT_CODE_NOT_SPECIFIED_LEGAL_TARGET_COMMAND"))
|
429
344
|
end
|
430
345
|
else
|
431
|
-
@mes.output_error("Not specified legal target command")
|
346
|
+
@mes.output_error("Not specified legal target command 3")
|
432
347
|
exit(@mes.ec("EXIT_CODE_NOT_SPECIFIED_LEGAL_TARGET_COMMAND"))
|
433
348
|
end
|
434
349
|
end
|
435
350
|
|
436
351
|
#
|
437
|
-
#
|
438
|
-
#
|
352
|
+
# サブコンポーネント指定のフィールドの値からサブターゲットストラクト生成
|
353
|
+
#
|
354
|
+
# @param fields [Array] カテゴリ別設定ファイルでのサブコンポーネント指定のフィールドの配列
|
439
355
|
# @param target_name [String] ターゲット名
|
440
356
|
# @param target_command [String] ターゲットコマンド名
|
441
357
|
# @param subtarget_command [String] サブターゲットコマンド名
|
442
|
-
# @
|
443
|
-
|
444
|
-
def setup_category_oneline_sub(fields, target_name, target_command, subtarget_command, category_x)
|
358
|
+
# @return [Array] 第0要素: サブターゲットストラクト 第1要素: サブターゲット名 第2要素: HTMLファイル名
|
359
|
+
def setup_category_oneline_sub(fields, target_name, target_command, subtarget_command)
|
445
360
|
if fields.size >= (@htmlfile_index + 1)
|
446
361
|
htmlfname = fields[@htmlfile_index]
|
447
362
|
else
|
@@ -455,39 +370,36 @@ module Md2site
|
|
455
370
|
misc = fields
|
456
371
|
target_dir = File.join(@src_dir, target_name)
|
457
372
|
|
458
|
-
unless @
|
373
|
+
unless @category_target[target_name]
|
459
374
|
tds = @target_struct.new(target_name, target_dir, nil, nil, nil, nil, nil, nil, nil, nil, target_command, nil, nil, [])
|
460
|
-
@
|
375
|
+
@category_target[target_name] = @category_target_struct.new(tds, misc, {}, {})
|
461
376
|
end
|
462
377
|
unless @commands[target_command]
|
463
|
-
@commands[target_command] ||=
|
378
|
+
@commands[target_command] ||= @command_struct.new(@category_target[target_name].target, {})
|
464
379
|
end
|
465
380
|
except = htmlfname.index("/") ? true : false
|
466
381
|
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
category_x[:category][target_name][subtarget_name] = fields
|
382
|
+
subtarget_name, htmlfname_x, htmldir, mdfname = normalize_htmlpath(htmlfname)
|
383
|
+
subtarget_name_x = subtarget_name.dup
|
471
384
|
|
472
|
-
subtarget_dir = File.join(target_dir,
|
385
|
+
subtarget_dir = File.join(target_dir, subtarget_name_x)
|
473
386
|
|
474
387
|
subtarget_data_dir = File.join(subtarget_dir, @data_dir)
|
475
388
|
subtarget_work_dir = File.join(subtarget_dir, @work_dir)
|
476
389
|
subtarget_material_dir = File.join(subtarget_dir, @material_dir)
|
477
390
|
|
478
391
|
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,
|
392
|
+
[stds, subtarget_name, htmlfname]
|
480
393
|
end
|
481
394
|
|
482
395
|
#
|
483
|
-
#
|
484
|
-
#
|
485
|
-
#
|
396
|
+
# カテゴリ別設定ファイル内の1つのサブコンポーネント指定でのターゲット名引きカテゴリ・ターゲットストラクトハッシュ、
|
397
|
+
# ターゲットコマンド名引きコマンドストラクトハッシュの設定
|
398
|
+
#
|
399
|
+
# @param fields [Array] サイト固有設定ファイルでのサブカテゴリ指定のフィールドの配列
|
486
400
|
# @param file_path [String] カテゴリ別設定ファイルへのパス
|
487
|
-
|
488
|
-
|
489
|
-
category_x[:category] ||= {}
|
490
|
-
|
401
|
+
# @return [void]
|
402
|
+
def setup_category_oneline(fields, file_path)
|
491
403
|
target_command = fields[@target_command_index]
|
492
404
|
subtarget_command = fields[@subtarget_command_index]
|
493
405
|
target_name = fields[@key_index]
|
@@ -496,18 +408,17 @@ module Md2site
|
|
496
408
|
exit(@mes.ec("EXIT_CODE_CANNOT_GET_TARGET"))
|
497
409
|
end
|
498
410
|
|
499
|
-
|
500
|
-
|
501
|
-
stds, subtarget, htmlfname = setup_category_oneline_sub(fields, target_name, target_command, subtarget_command, category_x)
|
411
|
+
stds, subtarget, htmlfname = setup_category_oneline_sub(fields, target_name, target_command, subtarget_command)
|
502
412
|
|
503
413
|
setup_category_oneline_x(target_command, subtarget_command, stds, target_name, subtarget, htmlfname)
|
504
414
|
end
|
505
415
|
|
506
416
|
#
|
507
|
-
#
|
508
|
-
#
|
417
|
+
# サイト構成ファイルからターゲット名引きカテゴリ・ターゲットストラクトハッシュの設定(無効な指定があればexitする)
|
418
|
+
#
|
419
|
+
# @param file_path [String] サイト構成ファイルへのパス
|
420
|
+
# @return [void]
|
509
421
|
def setup_category(file_path)
|
510
|
-
category_x = { array: [], category: {} }
|
511
422
|
@mes.exc_file_gets(file_path) do
|
512
423
|
f = File.open(file_path)
|
513
424
|
while (l = f.gets)
|
@@ -528,49 +439,82 @@ module Md2site
|
|
528
439
|
@mes.output_fatal("Invalid htmlfileIndex(=#{@htmlfile_index})")
|
529
440
|
exit(@mes.ec("EXIT_CODE_INVALID_INDEX"))
|
530
441
|
end
|
531
|
-
setup_category_oneline(array,
|
442
|
+
setup_category_oneline(array, file_path)
|
532
443
|
end
|
533
444
|
f.close
|
534
445
|
end
|
535
|
-
category_x
|
536
446
|
end
|
537
447
|
|
538
448
|
#
|
539
|
-
#
|
540
|
-
#
|
541
|
-
# @param
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
449
|
+
# サイト構成ファイルとカテゴリ構成ファイルの検査(異常があればデバッグ用エラーメッセージ出力)
|
450
|
+
#
|
451
|
+
# @param category_target_struct [Struct] 検査対象のカテゴリ・ターゲットストラクト
|
452
|
+
# @param obj [Hash] カテゴリ構成設定ファイル(YAML形式)を変換したハッシュ
|
453
|
+
# @return [void]
|
454
|
+
def check_site_tsv_and_category_conf(category_target_struct, obj)
|
455
|
+
category_subtarget_names = category_target_struct.subTargets.keys
|
456
|
+
target_conf_subtarget_names = obj.keys
|
457
|
+
|
458
|
+
ctkeys = category_subtarget_names - target_conf_subtarget_names
|
459
|
+
unless ctkeys.empty?
|
460
|
+
puts "target name=#{category_target_struct.target.name} category_only=#{ctkeys}"
|
461
|
+
end
|
462
|
+
tckeys = target_conf_subtarget_names - category_subtarget_names
|
463
|
+
unless tckeys.empty?
|
464
|
+
puts "target name=#{category_target_struct.target.name} site_only=#{tckeys}"
|
465
|
+
end
|
466
|
+
puts "==============" unless ctkeys.empty? || tckeys.empty?
|
467
|
+
end
|
553
468
|
|
469
|
+
#
|
470
|
+
# templateストラクトの作成
|
471
|
+
#
|
472
|
+
# @param line [String] サブコンポーネント指定
|
473
|
+
# @param subtarget [Struct] サブターゲットストラクト
|
474
|
+
# @return [Strunct] templateストラクト
|
475
|
+
def make_template_struct(line, subtarget)
|
476
|
+
name, template, misc = line.split(",")
|
477
|
+
macroname = name
|
478
|
+
name_x = name.dup
|
479
|
+
name_x[OUTPUT_DIR] = "" if name_x.index(OUTPUT_DIR)
|
480
|
+
|
481
|
+
outputfname = File.join(subtarget.workDir, %Q(#{name_x}.md))
|
482
|
+
|
483
|
+
src_subtarget_name = nil
|
484
|
+
if template == INCLUDE_INDICATOR
|
485
|
+
kind = :INCLUDE
|
486
|
+
datafname = File.join(misc, %Q(#{name_x}.md))
|
487
|
+
src_subtarget_name = name
|
488
|
+
else
|
489
|
+
kind = :NORMAL
|
490
|
+
datafname = File.join(subtarget.dataDir, %Q(#{name_x}.yml))
|
491
|
+
end
|
492
|
+
@template_struct.new(datafname, template, outputfname, macroname, kind, src_subtarget_name)
|
493
|
+
end
|
494
|
+
|
495
|
+
#
|
496
|
+
# カテゴリ構成ファイルの内容をカテゴリ・ターゲットストラクトに反映する
|
497
|
+
#
|
498
|
+
# @param category_target_struct [Struct] カテゴリ・ターゲットストラクト
|
499
|
+
# @param obj [Hash] カテゴリ構成ファイル(YAML形式)を変換したハッシュ
|
500
|
+
# @return [void]
|
501
|
+
def setup_target_config(category_target_struct, obj)
|
502
|
+
check_site_tsv_and_category_conf(category_target_struct, obj)
|
503
|
+
|
504
|
+
category_target_struct.subTargets.each do |_k, subtarget|
|
505
|
+
subtarget.filedir = @filedir_struct.new(File.join(@root_output_dir, subtarget.htmldir, subtarget.htmlfile).to_s,
|
506
|
+
File.join(subtarget.materialDir, subtarget.htmlfile).to_s,
|
507
|
+
File.join(subtarget.materialDir, "0.html").to_s,
|
508
|
+
File.join(subtarget.materialDir, "2.html").to_s,
|
509
|
+
File.join(subtarget.dataDir, subtarget.mdfile).to_s,
|
510
|
+
File.join(subtarget.workDir, subtarget.mdfile).to_s,
|
511
|
+
File.join(@root_output_dir, subtarget.htmldir, subtarget.mdfile).to_s,
|
512
|
+
subtarget.dataDir.to_s)
|
513
|
+
subtarget_name = subtarget.name
|
554
514
|
next unless obj && obj[subtarget_name]
|
555
515
|
|
556
|
-
obj[subtarget_name].each do |
|
557
|
-
|
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)
|
516
|
+
obj[subtarget_name].each do |line|
|
517
|
+
subtarget.templates << make_template_struct(line, subtarget)
|
574
518
|
end
|
575
519
|
end
|
576
520
|
end
|
@@ -578,8 +522,9 @@ module Md2site
|
|
578
522
|
#
|
579
523
|
# 全カテゴリに対して、対応するカテゴリ別設定ファイルの内容を反映する
|
580
524
|
#
|
525
|
+
# @return [void]
|
581
526
|
def setup_config
|
582
|
-
@
|
527
|
+
@category_target.each do |name, category_target_struct|
|
583
528
|
target = name
|
584
529
|
targetconf_yamlfile = %Q(#{@category_conf_prefix}#{target}.yml)
|
585
530
|
targetconf_yamlpath = File.join(@absolute_path_root_conf, targetconf_yamlfile)
|
@@ -588,10 +533,16 @@ module Md2site
|
|
588
533
|
exit(@mes.ec("EXIT_CODE_CANNOT_FIND_TARGETCONFYAMLPATH"))
|
589
534
|
end
|
590
535
|
obj = Filex::Filex.check_and_load_yamlfile(targetconf_yamlpath, @mes)
|
591
|
-
|
536
|
+
next unless obj
|
537
|
+
setup_target_config(category_target_struct, obj)
|
592
538
|
end
|
593
539
|
end
|
594
540
|
|
541
|
+
#
|
542
|
+
# パスを絶対パスに変換
|
543
|
+
#
|
544
|
+
# @param path [String,nil] nilでなければ引数pathの絶対パス
|
545
|
+
# @return [String] 絶対パス
|
595
546
|
def get_filepath(path)
|
596
547
|
if path
|
597
548
|
@mes.output_debug("0 path=#{path}")
|
@@ -608,14 +559,27 @@ module Md2site
|
|
608
559
|
abs_path
|
609
560
|
end
|
610
561
|
|
562
|
+
#
|
563
|
+
# makeサブコマンドの指定可能なターゲットコマンド名とサブターゲットコマンド名のオプション指定の組み合わせを返す
|
564
|
+
#
|
565
|
+
# @return [String] makeサブコマンドの指定可能なターゲットコマンド名とサブターゲットコマンド名のオプション指定の組み合わせ
|
611
566
|
def make_zlist
|
612
|
-
@commands.map {|t_name,
|
567
|
+
@commands.map {|t_name, command_struct| command_struct[:subtargets].map {|_, s_hash| %Q(-t #{t_name} -s #{s_hash['command']}) } }.flatten
|
613
568
|
end
|
614
569
|
|
615
|
-
|
616
|
-
|
570
|
+
#
|
571
|
+
# HTMLのアンカータグを生成
|
572
|
+
#
|
573
|
+
# @param subtarget [Struct] サブターゲットストラクト
|
574
|
+
# @return [String] HTMLのアンカータグ
|
575
|
+
def make_anchor_tag(subtarget)
|
576
|
+
%Q(<li><a href="#{subtarget.htmlfile}">#{subtarget.htmlfile}}</a></li>)
|
617
577
|
end
|
618
578
|
|
579
|
+
#
|
580
|
+
# HTMLの先頭部分の作成
|
581
|
+
#
|
582
|
+
# @return [String] HTMLの先頭部分
|
619
583
|
def make_html_first
|
620
584
|
<<~_HTML_HEAD
|
621
585
|
<html>
|
@@ -626,6 +590,10 @@ module Md2site
|
|
626
590
|
_HTML_HEAD
|
627
591
|
end
|
628
592
|
|
593
|
+
#
|
594
|
+
# HTMLの末尾部分の作成
|
595
|
+
#
|
596
|
+
# @return [String] HTMLの末尾部分
|
629
597
|
def make_html_last
|
630
598
|
<<~_HTML_BODY_TAIL
|
631
599
|
</ul>
|
@@ -634,16 +602,20 @@ module Md2site
|
|
634
602
|
_HTML_BODY_TAIL
|
635
603
|
end
|
636
604
|
|
605
|
+
#
|
606
|
+
# リンクの一覧のHTMLファイル作成
|
607
|
+
#
|
608
|
+
# @return [void]
|
637
609
|
def make_zindex_html
|
638
610
|
fname = File.join(@absolutepath_root, @root_output_dir, ZINDEX_HTML_FILE)
|
639
611
|
@mes.exc_file_write(fname) do
|
640
612
|
f = File.open(fname, "w")
|
641
613
|
f.puts(make_html_first)
|
642
|
-
|
643
|
-
f.puts(
|
614
|
+
anchors = @commands.map {|_, command_sturct| command_sturct[:subtargets].map {|_, subtarget| make_anchor_tag(subtarget) } }
|
615
|
+
f.puts(anchors.flatten.join("\n"))
|
644
616
|
f.puts(make_html_last)
|
645
617
|
f.close
|
646
618
|
end
|
647
619
|
end
|
648
620
|
end
|
649
|
-
end
|
621
|
+
end
|