|
| 1 | +function H = genHelp(F, L) |
| 2 | +% |
| 3 | +% Generates help struct array "H" from struct array "F" (functions) and |
| 4 | +% additional information coded directly here (non-functions), and saves it |
| 5 | +% in file "help.mat" |
| 6 | +% |
| 7 | +% Luis Mendo. |
| 8 | + |
| 9 | + |
| 10 | +N = 65; % characters per line |
| 11 | + |
| 12 | +% Non-functions. Changes done here should be don in `genHelp.m` too |
| 13 | + |
| 14 | +% Statements that are not functions. Changes done here to the comment field should be |
| 15 | +% done in `matl_disp.m` too. |
| 16 | +F(end+1).source = '"'; |
| 17 | +F(end).comment = 'for'; |
| 18 | +F(end).description = '\matlab+for+ (control flow: loop). \sa \matl+]+, \matl+@+, \matl+X}+, \matl+Y}+'; |
| 19 | + |
| 20 | +F(end+1).source = '`'; |
| 21 | +F(end).comment = 'do...while'; |
| 22 | +F(end).description = 'do...while (control flow: loop). \sa \matl+X`+, \matl+]+, \matl+@+, \matl+X}+, \matl+Y}+'; |
| 23 | + |
| 24 | +F(end+1).source = 'X`'; |
| 25 | +F(end).comment = 'while'; |
| 26 | +F(end).description = '\matlab+while+ (control flow: loop). \sa \matl+`+, \matl+]+, \matl+@+, \matl+X}+, \matl+Y}+'; |
| 27 | + |
| 28 | +F(end+1).source = '?'; |
| 29 | +F(end).comment = 'if'; |
| 30 | +F(end).description = '\matlab+if+ (control flow: conditional branch). \sa \matl+]+, \matl+}+'; |
| 31 | + |
| 32 | +F(end+1).source = '}'; |
| 33 | +F(end).comment = 'else'; |
| 34 | +F(end).description = '\matlab+else+ (control flow: conditional branch). \sa \matl+?+'; |
| 35 | + |
| 36 | +F(end+1).source = '@'; |
| 37 | +F(end).comment = 'for loop variable or do...while / while loop iteration index'; |
| 38 | +F(end).description = 'for loop variable, do...while loop iteration index or while loop iteration index of innermost loop'; |
| 39 | + |
| 40 | +F(end+1).source = ']'; |
| 41 | +F(end).comment = 'end'; |
| 42 | +F(end).description = '\matlab+end+ (control flow). End loop or conditional branch. \sa \matl+"+, \matl+`+, \matl+?+'; |
| 43 | + |
| 44 | +F(end+1).source = '.'; |
| 45 | +F(end).comment = 'conditional break'; |
| 46 | +F(end).description = 'conditional \matlab+break+ (control flow: loop). Consume the top of the stack and, if it evaluates to ''true'' acccording to \matlab+if+ rules, terminate execution of innermost loop. \sa \matl+"+, \matl+`+'; |
| 47 | + |
| 48 | +F(end+1).source = 'X.'; |
| 49 | +F(end).comment = 'conditional continue'; |
| 50 | +F(end).description = 'conditional \matlab+continue+ (control flow: loop). Consume the top of the stack and, if it evaluates to ''true'' acccording to \matlab+if+ rules, pass control to next iteration of innermost loop. \sa \matl+"+, \matl+`+'; |
| 51 | + |
| 52 | +F(end+1).source = ''''; |
| 53 | +F(end).comment = 'string delimiter'; |
| 54 | +F(end).description = 'string delimiter. Should be doubled when used within a string'; |
| 55 | + |
| 56 | +F(end+1).source = ','; |
| 57 | +F(end).comment = 'separator'; |
| 58 | +F(end).description = 'separator. Space and newline can be used as separators too'; |
| 59 | + |
| 60 | +F(end+1).source = '%'; |
| 61 | +F(end).comment = 'comment'; |
| 62 | +F(end).description = 'comment. The rest of the line is ignored'; |
| 63 | + |
| 64 | +% Sort according to source |
| 65 | +[~, ind] = sort(cellfun(@(x) x(end:-1:1), {F.source}, 'UniformOutput', 0)); |
| 66 | +F = F(ind); |
| 67 | + |
| 68 | +commFormatted = {F.comment}; |
| 69 | +descrFormatted = {F.description}; |
| 70 | +descrFormatted = regexprep(descrFormatted, '\\matlab(.)(.*?)(\1)', '<strong>$2</strong>'); |
| 71 | +descrFormatted = regexprep(descrFormatted, '\\matl\+(.*?)\+', '<strong>$1</strong>'); %***make delimiter arbitrary her too |
| 72 | +descrFormatted = regexprep(descrFormatted, '\\comp{(.*?)}', '<strong>$1</strong>'); |
| 73 | +descrFormatted = regexprep(descrFormatted, '\\sa', 'See also'); |
| 74 | +descrFormatted = regexprep(descrFormatted, '\$(.*?)\$', '$1'); |
| 75 | +descrPlain = cell(1,numel(descrFormatted)); |
| 76 | +inFormatted = cell(1,numel(descrFormatted)); |
| 77 | +outFormatted = cell(1,numel(descrFormatted)); |
| 78 | +sourceFormatted = cell(1,numel(descrFormatted)); |
| 79 | +sourcePlain = {F.source}; |
| 80 | + |
| 81 | +for n = 1:numel(descrFormatted) |
| 82 | + % Format source |
| 83 | + sourceFormatted{n} = ['<strong>' F(n).source '</strong>']; |
| 84 | + |
| 85 | + % Add information on predefined literals, if applicable |
| 86 | + if ~isempty(regexp(F(n).source,'[XYZ]\d','once')) && isfield(L, (F(n).source)) % X0...Z9 that are defined |
| 87 | + aux = [num2cell(L.(F(n).source).key); L.(F(n).source).val]; |
| 88 | + descrFormatted{n} = [ descrFormatted{n} '. ' sprintf('%i: %s; ', aux{:})]; |
| 89 | + end |
| 90 | + |
| 91 | + % Format description |
| 92 | + descrFormatted{n}(end+1) = ' '; % needed so that the "find" line always finds last index |
| 93 | + [s, e] = regexp(descrFormatted{n},'<strong>','start','end'); |
| 94 | + descrMask = true(1,numel(descrFormatted{n})); |
| 95 | + descrSpace = false(1,numel(descrFormatted{n})); |
| 96 | + for m = 1:numel(s) |
| 97 | + descrMask(s(m):e(m)) = false; |
| 98 | + end |
| 99 | + [s, e] = regexp(descrFormatted{n},'</strong>','start','end'); |
| 100 | + for m = 1:numel(s) |
| 101 | + descrMask(s(m):e(m)) = false; |
| 102 | + end |
| 103 | + descrPlain{n} = descrFormatted{n}(descrMask); |
| 104 | + s = regexp(descrFormatted{n},'\s','start'); |
| 105 | + descrSpace(s) = true; |
| 106 | + d = {}; |
| 107 | + while ~isempty(descrMask) |
| 108 | + c = cumsum(descrMask); |
| 109 | + ind = find((c<=N)& descrSpace, 1, 'last'); |
| 110 | + d{end+1} = descrFormatted{n}(1:ind); |
| 111 | + descrFormatted{n}(1:ind) = []; |
| 112 | + descrMask(1:ind) = []; |
| 113 | + descrSpace(1:ind) = []; |
| 114 | + end |
| 115 | + % descrFormatted{n} = char(d); % gives a char 2D array. Bad for searching |
| 116 | + d = sprintf(' %s\n', d{:}); % four spaces for left margin |
| 117 | + descrFormatted{n} = d(1:end-1); % remove last '\n' |
| 118 | + |
| 119 | + % Format input spec: |
| 120 | + minIn = str2double(F(n).minIn); |
| 121 | + maxIn = str2double(F(n).maxIn); |
| 122 | + defIn = str2double(F(n).defIn); |
| 123 | + minOut = str2double(F(n).minOut); |
| 124 | + maxOut = str2double(F(n).maxOut); |
| 125 | + defOut = str2double(F(n).defOut); |
| 126 | + |
| 127 | + if isnan(defIn) && ~isempty(F(n).defIn) % F(n).defIn contains a string that couldn't be converted to a number |
| 128 | + switch F(n).defIn |
| 129 | + case 'numel(STACK)' |
| 130 | + defInStr = 'number of elements in stack'; |
| 131 | + otherwise |
| 132 | + error('Unrecognized default number of inputs') |
| 133 | + end |
| 134 | + else |
| 135 | + defInStr = sprintf('%i', defIn); |
| 136 | + end |
| 137 | + |
| 138 | + if isempty(F(n).minIn) || isempty(F(n).maxIn) |
| 139 | + inFormatted{n} = []; |
| 140 | + elseif minIn ~= maxIn |
| 141 | + if isfinite(maxIn) |
| 142 | + inFormatted{n} = sprintf('%i--%i (%s)', minIn, maxIn, defInStr); |
| 143 | + else |
| 144 | + inFormatted{n} = sprintf('%i-- (%s)', minIn, defInStr); |
| 145 | + end |
| 146 | + else |
| 147 | + if maxIn ~= defIn |
| 148 | + error('Incorrect specification of number of inputs') |
| 149 | + end |
| 150 | + inFormatted{n} = sprintf('%i', defIn); |
| 151 | + end |
| 152 | + |
| 153 | + % Format output spec: |
| 154 | + if isnan(defOut) && ~isempty(F(n).defOut) % F(n).defOut contains a string that couldn't be converted to a number |
| 155 | + switch F(n).defOut |
| 156 | + case {'numel(CB_H)' 'numel(CB_I)' 'numel(CB_J)' 'numel(CB_K)'} |
| 157 | + defOutStr = 'number of elements in clipboard'; |
| 158 | + case 'numel(CB_L{in{1}})' |
| 159 | + defOutStr = 'number of elements in clipboard level'; |
| 160 | + case 'numel(in{1})' |
| 161 | + defOutStr = 'number of elements of first input'; |
| 162 | + otherwise |
| 163 | + error('Unrecognized default number of outputs') |
| 164 | + end |
| 165 | + else |
| 166 | + defOutStr = sprintf('%i', defOut); |
| 167 | + end |
| 168 | + |
| 169 | + if isempty(F(n).minOut) || isempty(F(n).maxOut) |
| 170 | + outFormatted{n} = []; |
| 171 | + elseif minOut ~= maxOut |
| 172 | + if isfinite(maxOut) |
| 173 | + outFormatted{n} = sprintf('%i--%i (%s)', minOut, maxOut, defOutStr); |
| 174 | + else |
| 175 | + outFormatted{n} = sprintf('%i-- (%s)', minOut, defOutStr); |
| 176 | + end |
| 177 | + else |
| 178 | + if maxOut ~= defOut |
| 179 | + error('Incorrect specification of number of inputs') |
| 180 | + end |
| 181 | + outFormatted{n} = sprintf('%i', defOut); |
| 182 | + end |
| 183 | +end |
| 184 | + |
| 185 | +H.source = sourceFormatted; |
| 186 | +H.comm = commFormatted; |
| 187 | +H.descr = descrFormatted; |
| 188 | +H.in = inFormatted; |
| 189 | +H.out = outFormatted; |
| 190 | +H.sourcePlain = sourcePlain; |
| 191 | +H.descrPlain = descrPlain; |
| 192 | +save help H |
| 193 | + |
| 194 | + |
0 commit comments