-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPrintExamples.m
More file actions
139 lines (123 loc) · 3.5 KB
/
PrintExamples.m
File metadata and controls
139 lines (123 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
function status = PrintExamples(theFunction,varargin)
% Open file, read it, parse and print the examples
%
% Syntax:
% status = PrintExamples(theFunction, varargin)
%
% Description:
% A comment line followed by a
%
% % Examples:
% %{
% ...
% %}
% %{
% ...
% %}
%
% Indicates that the text in block quotes are examples. The
% examples block is terminated by a blank line.
%
% Inputs:
% theFunction - String. Name of a function on the user's path.
% which(theFunction) should return the full path to the function.
%
% Outputs:
% status - What happened?
% -1: Found examples but at least one crashed, or other
% error such as unmatched block comment open and
% close.
% 0: No examples found
% N: With N > 0. Number of examples printed.
%
% Optional key/value pairs:
% 'verbose' - Boolean. Be verbose? Default false
%
% Examples are provided in the code.
%
% See also:
%
%
% History
% 01/16/18 bw First implementation
% Examples:
%{
% Should execute both examples successfully
PrintExamples('ExecuteTextInScript');
%}
%% Parse input
p = inputParser;
p.addRequired('theFunction',@(x)(exist(x,'file')))
p.addParameter('verbose',false,@islogical);
p.parse(theFunction,varargin{:});
%% Open file
fullFileName = which(theFunction);
theFileH = fopen(fullFileName,'r');
theText = {char(fread(theFileH,'uint8=>char')')};
fclose(theFileH);
% Say hello
if (p.Results.verbose)
fprintf('Looking for and running examples in %s\n',theFunction);
end
if (strcmp(theFunction,[mfilename '.m']))
if (p.Results.verbose)
fprintf('Not running on self to prevent recursion');
end
status = 0;
return;
end
%% Look for a comment line with the text " Examples:"
ind = strfind(theText{1},'% Examples:');
if (isempty(ind))
if (p.Results.verbose)
fprintf('\tNo comment line starting with "%% Examples:" in file\n');
end
status = 0;
return;
end
% Look for examples
candidateText = theText{1}(ind(1)+9:end);
startIndices = strfind(candidateText,'%{');
endIndices = strfind(candidateText,'%}');
if (isempty(startIndices))
if (p.Results.verbose)
fprintf('\tNo block comment starts in file\n');
end
status = 0;
return;
end
if (length(startIndices) ~= length(endIndices))
if (p.Results.verbose)
fprintf('\tNumber of block comment ends does not match number of starts.\n');
end
status = -1;
return;
end
%% Start the printing
cnt = 0;
fprintf('\n\n');
for bb = 1:length(startIndices)
cnt = cnt+1;
fprintf('Example %d \n----------\n',cnt);
% Find the end of line for the %{ part. Sometimes people put in
% extra spaces, so we need to actually find the EOL.
% Putting this '%}' prevents and ETTB error because number of open and
% close block comment symbols must match up in the file.
idx = find(int8(candidateText(startIndices(bb):(startIndices(bb)+8))) == 10);
% Pull out the example text
exampleText = candidateText((startIndices(bb) + idx):endIndices(bb)-1);
% Print it
disp(exampleText);
% If this is not the last block comment, check whether the next one is
% contiguous. If not, we're done with examples and break out and go
% home.
if (bb < length(startIndices))
if (endIndices(bb)+3 <= length(candidateText))
if (candidateText(endIndices(bb)+3) ~= '%')
break;
end
end
end
end
status = cnt;
end