@@ -6,6 +6,7 @@ if not dfhack_flags.module then
6
6
end
7
7
8
8
local utils = require (' utils' )
9
+ local xlsxreader = require (' plugins.xlsxreader' )
9
10
local quickfort_common = reqscript (' internal/quickfort/common' )
10
11
local quickfort_parse = reqscript (' internal/quickfort/parse' )
11
12
20
21
21
22
local blueprint_cache = {}
22
23
23
- local function scan_blueprint (path )
24
+ local function scan_csv_blueprint (path )
24
25
local filepath = quickfort_common .get_blueprint_filepath (path )
25
26
local mtime = dfhack .filesystem .mtime (filepath )
26
27
if not blueprint_cache [path ] or blueprint_cache [path ].mtime ~= mtime then
27
28
blueprint_cache [path ] = {modeline = get_modeline (filepath ), mtime = mtime }
28
29
end
30
+ if not blueprint_cache [path ].modeline then
31
+ print (string.format (' skipping "%s": no #mode marker detected' , path ))
32
+ end
29
33
return blueprint_cache [path ].modeline
30
34
end
31
35
32
- local blueprint_files = {}
36
+ local function get_xlsx_sheet_modeline (xlsx_file , sheet_name )
37
+ local xlsx_sheet = xlsxreader .open_sheet (xlsx_file , sheet_name )
38
+ return dfhack .with_finalize (
39
+ function () xlsxreader .close_sheet (xlsx_sheet ) end ,
40
+ function ()
41
+ local row_cells = xlsxreader .get_row (xlsx_sheet )
42
+ if not row_cells or # row_cells == 0 then return nil end
43
+ return quickfort_parse .parse_modeline (row_cells [1 ])
44
+ end
45
+ )
46
+ end
47
+
48
+ local function get_xlsx_file_sheet_infos (filepath )
49
+ local sheet_infos = {}
50
+ local xlsx_file = xlsxreader .open_xlsx_file (filepath )
51
+ if not xlsx_file then return sheet_infos end
52
+ return dfhack .with_finalize (
53
+ function () xlsxreader .close_xlsx_file (xlsx_file ) end ,
54
+ function ()
55
+ for _ , sheet_name in ipairs (xlsxreader .list_sheets (xlsx_file )) do
56
+ local modeline = get_xlsx_sheet_modeline (xlsx_file , sheet_name )
57
+ if modeline then
58
+ table.insert (sheet_infos ,
59
+ {name = sheet_name , modeline = modeline })
60
+ end
61
+ end
62
+ return sheet_infos
63
+ end
64
+ )
65
+ end
66
+
67
+ local function scan_xlsx_blueprint (path )
68
+ local filepath = quickfort_common .get_blueprint_filepath (path )
69
+ local mtime = dfhack .filesystem .mtime (filepath )
70
+ if blueprint_cache [path ] and blueprint_cache [path ].mtime == mtime then
71
+ return blueprint_cache [path ].sheet_infos
72
+ end
73
+ local sheet_infos = get_xlsx_file_sheet_infos (filepath )
74
+ if # sheet_infos == 0 then
75
+ print (string.format (
76
+ ' skipping "%s": no sheet with #mode markers detected' , path ))
77
+ end
78
+ blueprint_cache [path ] = {sheet_infos = sheet_infos , mtime = mtime }
79
+ return sheet_infos
80
+ end
81
+
82
+ local blueprints = {}
33
83
34
84
local function scan_blueprints ()
35
85
local paths = dfhack .filesystem .listdir_recursive (
36
86
quickfort_common .settings [' blueprints_dir' ].value , nil , false )
37
- blueprint_files = {}
38
- local library_files = {}
87
+ blueprints = {}
88
+ local library_blueprints = {}
39
89
for _ , v in ipairs (paths ) do
40
- if not v .isdir and
41
- (string.find (v .path , ' [.]csv$' ) or
42
- string.find (v .path , ' [.]xlsx$' )) then
43
- if string.find (v .path , ' [.]xlsx$' ) then
44
- print (string.format (
45
- ' skipping "%s": .xlsx files not supported yet' , v .path ))
46
- goto skip
90
+ local is_library = string.find (v .path , ' ^library/' ) ~= nil
91
+ local target_list = blueprints
92
+ if is_library then target_list = library_blueprints end
93
+ if not v .isdir and string.find (v .path :lower (), ' [.]csv$' ) then
94
+ local modeline = scan_csv_blueprint (v .path )
95
+ if modeline then
96
+ table.insert (target_list ,
97
+ {path = v .path , modeline = modeline , is_library = is_library })
47
98
end
48
- local modeline = scan_blueprint (v .path )
49
- if not modeline then
50
- print (string.format (
51
- ' skipping "%s": no #mode marker detected' , v .path ))
52
- goto skip
99
+ elseif not v .isdir and string.find (v .path :lower (), ' [.]xlsx$' ) then
100
+ local sheet_infos = scan_xlsx_blueprint (v .path )
101
+ if # sheet_infos > 0 then
102
+ for _ , sheet_info in ipairs (sheet_infos ) do
103
+ table.insert (target_list ,
104
+ {path = v .path ,
105
+ sheet_name = sheet_info .name ,
106
+ modeline = sheet_info .modeline ,
107
+ is_library = is_library })
108
+ end
53
109
end
54
- if string.find (v .path , ' ^library/' ) ~= nil then
55
- table.insert (
56
- library_files ,
57
- {path = v .path , modeline = modeline , is_library = true })
58
- else
59
- table.insert (
60
- blueprint_files ,
61
- {path = v .path , modeline = modeline , is_library = false })
62
- end
63
- :: skip::
64
110
end
65
111
end
66
112
-- tack library files on to the end so user files are contiguous
67
- for i = 1 , # library_files do
68
- blueprint_files [ # blueprint_files + 1 ] = library_files [i ]
113
+ for i = 1 , # library_blueprints do
114
+ blueprints [ # blueprints + 1 ] = library_blueprints [i ]
69
115
end
70
116
end
71
117
72
118
function get_blueprint_by_number (list_num )
73
- if # blueprint_files == 0 then
119
+ if # blueprints == 0 then
74
120
scan_blueprints ()
75
121
end
76
- local blueprint_file = blueprint_files [list_num ]
77
- if not blueprint_file then
122
+ local blueprint = blueprints [list_num ]
123
+ if not blueprint then
78
124
qerror (string.format (' invalid list index: %d' , list_num ))
79
125
end
80
- return blueprint_file .path
126
+ return blueprint .path , blueprint . sheet_name
81
127
end
82
128
83
129
local valid_list_args = utils .invert ({
@@ -89,8 +135,12 @@ function do_list(in_args)
89
135
local args = utils .processArgs (in_args , valid_list_args )
90
136
local show_library = args [' l' ] ~= nil or args [' -library' ] ~= nil
91
137
scan_blueprints ()
92
- for i , v in ipairs (blueprint_files ) do
138
+ for i , v in ipairs (blueprints ) do
93
139
if show_library or not v .is_library then
140
+ local sheet_spec = ' '
141
+ if v .sheet_name then
142
+ sheet_spec = string.format (' -n "%s"' , v .sheet_name )
143
+ end
94
144
local comment = ' )'
95
145
if # v .modeline .comment > 0 then
96
146
comment = string.format (' : %s)' , v .modeline .comment )
@@ -100,8 +150,8 @@ function do_list(in_args)
100
150
start_comment = string.format (' ; cursor start: %s' ,
101
151
v .modeline .start_comment )
102
152
end
103
- print (string.format (' %d) "%s" (%s%s%s' ,
104
- i , v .path , v .modeline .mode , comment ,
153
+ print (string.format (' %d) "%s"%s (%s%s%s' ,
154
+ i , v .path , sheet_spec , v .modeline .mode , comment ,
105
155
start_comment ))
106
156
end
107
157
end
0 commit comments