FITS_data = {} function sanitize_line(line) local line = line:gsub("^%s*", "") return line end function strip_comment(line) local comment_index = line:find("%s+/%s+") if comment_index then return line:sub(1, comment_index - 1) else return line:gsub("%s*$", "") end end function load_fits(filename) local header = {} local general_match = "^([%w%-]+)%s*=%s*(.+)%s*" local end_match = "END%s*$" local filepath = kpse.find_file(filename) if not filepath then tex.print('\\luaescapestring{\\FITSerr{FITS file not found: ' .. filename .. '}}') else frame = io.open(filepath, 'rb') if not frame then tex.print('\\luaescapestring{\\FITSerr{Error opening FITS file: ' .. filename .. '}}') end repeat local line = frame:read(80) if not line then break end local new_line = strip_comment(sanitize_line(line)) local header_key, header_value = new_line:match(general_match) if header_key and header_value then header[header_key] = header_value end until line:match(end_match) or not line local count = 0 for k, v in pairs(header) do if v:sub(1, 1) == "'" and v:sub(-1, -1) == "'" then header[k] = v:sub(2, -2):gsub("%s*$", "") end end frame:close() end return header end function show_fits(header) for k, v in pairs(header) do texio.write_nl(k .. ': ' .. v) end texio.write('\n') end function get_header_key(header, key) local header_key = header[tostring(key)] if header_key ~= nil then tex.print(header_key) end end