📄 tfgparse.m
字号:
function parsed = tfgparse(varargin)% tfgparse - parses a BVQXfigure TFG file into a struct%% FORMAT: TFGstruct = tfgparse(filename [, options])% or% TFGstruct = tfgparse(TFGstruct, options)%% Input fields:%% filename name of the TFG file to parse% TFGstruct if given, write to TFG file or evaluate contents% options struct with optional fields% .check runs checksyntax on all Callback* fields% .evaluate evaluate VARIABLES and *,] fields%% The second format creates the file specified by filename from the% contents of TFGstruct.% Version: v0.7b% Build: 7090119% Date: Aug-31 2007, 9:36 PM CEST% Author: Jochen Weber, Brain Innovation, B.V., Maastricht, NL% URL / Info: http://wiki.brainvoyager.com/BVQXtools% persistent memorypersistent tfgparser;if isempty(tfgparser) % initialize struct tfgparser = struct; % callback functions to check tfgparser.cbcheck = { ... 'callback', ... 'callbackclreq', ... 'callbackdblclick' ... }; % default options tfgparser.defopts = { ... 'check', 'logical', {false, true}, false; ... 'evaluate', 'logical', {false, true}, true ... }; % empty structure tfgparser.parsed = struct( ... 'POPTIONS', struct('CommentFieldWidth', 16), ... 'COMMENTS', struct, ... 'VARIABLES', cell2struct(cell(0, 0, 2), ... {'VarName', 'VarContent'}, 3), ... 'FIGURE', cell2struct(cell(0, 0, 1), ... {'Position'}, 3), ... 'UICONTROLS', cell2struct(cell(0, 0, 3), ... {'Position', 'Tag', 'Type'}, 3), ... 'UIRESIZE', cell2struct(cell(0, 0, 3), ... {'Tag', 'Reference', 'RelPosition'}, 3), ... 'MENU', cell2struct(cell(0, 0, 4), ... {'Callback', 'Caption', 'Level', 'Tag'}, 3), ... 'CONTEXTMENUS', cell2struct(cell(0, 0, 5), ... {'IsCM', 'Callback', 'Caption', 'Level', 'Tag'}, 3) ... );end% argument checkif nargin < 1 || ... (~ischar(varargin{1}) && ... ~isstruct(varargin{1})) || ... isempty(varargin{1}) error( ... 'BVQXtools:BadArgument', ... 'Invalid number/type of arguments.' ... );endif nargin > 1 && ... isstruct(varargin{2}) options = checkstruct(varargin{2}, tfgparser.defopts, true);else options = checkstruct(struct, tfgparser.defopts);end% try to read TFG fileif ischar(varargin{1}) filename = varargin{1}(:)'; if exist(filename, 'file') ~= 2 error( ... 'BVQXtools:BadArgument', ... 'Filename not found.' ... ); end try [figtext, nlines] = splittocell(asciiread(filename), char([10, 13]), 1, 1); catch error( ... 'BVQXtools:BadArgument', ... 'TFG file not readable.' ... ); endelse filename = '';end% parsing fileif ~isempty(filename) % initialize output structure, just in case... parsed = tfgparser.parsed; figsbegins = zeros(1, nlines); figsends = zeros(1, nlines); figsnames = cell(1, nlines); % iterate through lines fc = 0; lc = 0; while lc < nlines lc = lc + 1; % section begin ? lcf = strfind(figtext{lc}, 'BEGIN_'); if ~isempty(lcf) % get section name tag psecbegin = lc; psecnamep = lcf(1)+6; psectname = figtext{psecbegin}(psecnamep:end); % valid name tag ? tr = find(psectname < 65 | ... (psectname > 90 & psectname < 97) | ... psectname > 122); if ~isempty(tr) psectname(tr(1):end) = []; end if isempty(psectname) continue; end % find section end lec = lc; while lec < nlines lec = lec + 1; lecf = strfind(figtext{lec}, ['END_' psectname]); if ~isempty(lecf) break; end end % if we're beyond EOF, don't use it! if lec > nlines lc = nlines + 1; continue; end % accept section psecend = lec; fc = fc + 1; figsbegins(fc) = psecbegin; figsends(fc) = psecend; figsnames{fc} = psectname; lc = lec; end end figsbegins = figsbegins(1:fc); figsends = figsends(1:fc); figsnames = figsnames(1:fc); % set final end marker figsbegins(end + 1) = nlines + 1; % iterate over sections readopts = struct('convert', 'deblank', 'headline', ''); numsects = length(figsnames); for sc = 1:numsects lrb = figsbegins(sc); lre = figsends(sc); sectname = figsnames{sc}; % handle comments specially if strcmp(upper(sectname), 'COMMENTS') for lc = (lrb + 1):(lre - 1) [comv, comc] = splittocell(figtext{lc}, ':'); if comc > 2 comv{2} = gluetostring(comv(2:end), ':'); end if comc < 2 comv{2} = ''; end while numel(comv{2} > 0) && ... comv{2}(1) == ' ' comv{2}(1) = []; end parsed.COMMENTS.(makelabel(comv{1})) = comv{2}; end parsed.COMMENTS.ALLCOMMENTS = ... gluetostring(figtext(lrb:lre), char(10), 1); % all other sections here else parsed.(upper(sectname)) = ... acsvread({figtext{lrb + 1:lre - 1}}, '|', readopts); end end % numbers are parsed definitely fn = fieldnames(parsed); for fc1 = 1:numel(fn) fp = parsed.(fn{fc1}); sfn = fieldnames(fp); for sc = 1:numel(fp) for fc2 = 1:numel(sfn) if ~isempty(fp(sc).(sfn{fc2})) && ... fp(sc).(sfn{fc2})(1) == '$' fp(sc).(sfn{fc2}) = ... eval(['[' fp(sc).(sfn{fc2})(2:end) ']'], '[]'); end end end parsed.(fn{fc1}) = fp; end% otherwiseelse parsed = varargin{1};end% evaluate the contents of the parsed TFGif options.evaluate if isfield(parsed, 'VARIABLES') && ... isstruct(parsed.VARIABLES) && ... isfield(parsed.VARIABLES, 'VarName') && ... isfield(parsed.VARIABLES, 'VarContent') tvars = parsed.VARIABLES; assignin('base', 'tfgtv', struct); % iterate over loaded variables for tvar = 1:numel(tvars) % no special character sequence (leading '*') if ~ischar(tvars(tvar).VarContent) || ... isempty(tvars(tvar).VarContent) || ... ~any('*$]' == tvars(tvar).VarContent(1)) try evalin('base', ['tfgtv.' tvars(tvar).VarName '=' ... tvars(tvar).VarContent]); catch error( ... 'BVQXfile:EvaluationError', ... 'Error evaluating expression for %s.', ... tvars(tvar).VarName ... ); end % evaluation elseif any(']$' == tvars(tvar).VarContent(1)) evalin('base', ['tfgtv.' tvars(tvar).VarName '=' ... tvars(tvar).VarContent(2:end) ';'], ... ''); % substitution else evalin('base', ['tfgtv.' tvars(tvar).VarName '=' ... 'tfgtv.' tvars(tvar).VarContent(2:end) ';'], ... ''); end end end fn = fieldnames(parsed); for fc1 = 1:numel(fn) if strcmpi(fn{fc1}, 'variables') continue; end fp = parsed.(fn{fc1}); sfn = fieldnames(fp); for sc = 1:numel(fp) for fc2 = 1:numel(sfn) if ischar(fp(sc).(sfn{fc2})) && ... ~isempty(fp(sc).(sfn{fc2})) && ... any('$]*' == fp(sc).(sfn{fc2})(1)) switch (fp(sc).(sfn{fc2})(1)) case {'$', ']'} fp(sc).(sfn{fc2}) = ... evalin('base', ['[' ... fp(sc).(sfn{fc2})(2:end) ']'], '[]'); case {'*'} fp(sc).(sfn{fc2}) = ... evalin('base', ['[tfgtv.' ... fp(sc).(sfn{fc2})(2:end) ']'], '[]'); end end end end parsed.(fn{fc1}) = fp; end try evalin('base', 'clear tfgtv;', ''); catch % do nothing endend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -