-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathFigError.m
More file actions
281 lines (177 loc) · 8.52 KB
/
Copy pathFigError.m
File metadata and controls
281 lines (177 loc) · 8.52 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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
(* ::Package:: *)
(*Header comments*)
(* :Title: FigError *)
(* :Context: SciDraw` *)
(* :Summary: Error passing and messaging utilities *)
(* :Author: Mark A. Caprio, Department of Physics, University of Notre Dame *)
(* :Copyright: Copyright FIGYEAR, Mark A. Caprio *)
(* :Package Version: FIGVERSION *)
(* :Mathematica Version: MATHVERSION *)
(* :Discussion: FIGDISCUSSION *)
(* :History: See main package file. *)
(*Begin package*)
(*Package context definition*)
BeginPackage["SciDraw`",SciDraw`Private`$ExternalContexts];
Unprotect[Evaluate[$Context<>"*"]];
(*Begin private context*)
Begin["`Private`"];
(*Dependencies*)
(*Error handling*)
(*Message emitter*)
(*Note: Separate message function saves evaluation problems. For instance, in an ordinary Message call,*)
(* Message[Evaluate[Evaluate[ObjectClass[Self]]::figobjname],...]*)
(*would be required since both MessageName and Message are HoldFirst. However, by passing the expressions through FigMessage, this reduces to*)
(* FigMessage[Self,figobjname,...].*)
(* *)
(*Note: Use of MessageName[f,m] is since f::m or f::Evaluate[m] does not accomplish proper replacement of parameter m. This is presumably since the symbol::tag notation converts tag to the string "tag" before parameter replacement can take place. On the other hand, with an argument of type m_Symbol, this form leads to full qualification of symbol (such as FigLine::SciDraw`Private`figobjname), which is also undesirable. Therefore, require strings for message names.*)
FigMessage[f_Symbol,m_String,Args___]:=Message[MessageName[f,m],Args];
FigMessage[s_Object,m_String,Args___]:=FigMessage[ObjectClass[s],m,Args];
(*Object identifier message*)
(*Grammatical note: Use of article "a" rather than "an" presumes all object names will begin with consonants.*)
General::figobj="While `1` a `2` object named \"`3`\"...";
General::figobjanon="While `1` a `2` object (no name specified)...";
(*Note on evaluation:*)
(* Context[Evaluate[ObjectName[Self]]] is since Context is HoldFirst.*)
(* Message[Evaluate[Evaluate[ObjectClass[Self]]::figobjname] is since both MessageName and Message are HoldFirst.*)
FigWarnObject[Self_Object,Action_String]:=If[
MatchQ[ObjectName[Self],_Symbol]&&Context[Evaluate[ObjectName[Self]]]==$ObjectInstanceContext,
FigMessage[SciDraw,"figobjanon",Action,ObjectClass[Self]],
FigMessage[SciDraw,"figobj",Action,ObjectClass[Self],ObjectName[Self]]
];
(*Error thrower*)
FigError[f_Symbol,m_String,Args___]:=Module[
{},
FigMessage[f,m,Args];
Abort[]
];
FigError[s_Object,m_String,Args___]:=Module[
{},
FigWarnObject[s,"constructing"];
FigMessage[s,m,Args];
Abort[]
];
FigError[MakeAnchor,s_Object,m_String,Args___]:=Module[
{},
FigWarnObject[s,"constructing an anchor for"];
FigMessage[s,m,Args];
Abort[]
];
FigError[MakeBoundingBox,s_Object,m_String,Args___]:=Module[
{},
FigWarnObject[s,"constructing the bounding region for"];
FigMessage[s,m,Args];
Abort[]
];
(*Object name validation*)
(*Formerly: Object names are recommended to be of the form*)
(* string EX: "shape"*)
(* symbol EX: A, MyObject*)
(* symbol[args] EX: Shape[35], Person["John", "Doe"]*)
(*where symbol is not in the System` context. This final condition eliminates such insidious cases as*)
(* 1/2 = Rational[1,2]*)
(* {1,2} = List[1,2].*)
(**)
(*Reconsideration: Actually, what was wrong with these forms? Names such as 1/2 are awkward since Mathematica has multiple internal representations. Head List is problematic if Flatten is applied to a list of object names. These forms were problematic in SciDraw early development, when object names were used directly as coordinates, and thus an object name which could be mistaken for a coordinate was ambiguous. However, object names are now only used in contexts in which only an object name would be accepted.*)
(**)
(*Presently: FigCheckObjectName is a no-op.*)
(*
NewSymbolPattern=((x_Symbol)/;(Context[x]=!="System`"));
SaneObjectNamePattern=NewSymbolPattern|NewSymbolPattern[___]|(_String);
General::figobjbadname="The object name `1` is not of the recommended form and might therefore lead to syntax ambiguities. For object names, it is recommended that you use a string (e.g., \"name\"), a new symbol (e.g., Name) not already defined as a Mathematica reserved symbol, or an expression headed by such a symbol (e.g., Name[1,2]).";
FigCheckObjectName[Self:Object[A_]/;!MatchQ[A,SaneObjectNamePattern]]:=
FigMessage[Self,"figobjbadname",ObjectName[Self]];
*)
FigCheckObjectName[Self:Object[A_]]:=Null;
(*Error for function use outside figure*)
General::notinfigobj="Attempted to create figure object outside of a figure.";General::notinfigfcn="This function may only be used inside a Figure environment.";
FigCheckInFigure[Self_Object]/;(!SciDraw`Private`$InFigure):=FigError[Self,"notinfigobj"];
FigCheckInFigure[Self_Symbol]/;(!SciDraw`Private`$InFigure):=FigError[Self,"notinfigfcn"];
(*Error for function with unmatched argument sequence*)
General::figargs="Missing or unexpected arguments in `1`.";
General::figargsnull="One of the arguments in `1` is Null. Check for extra commas among the arguments.";
SetAttributes[FigFallThroughError,HoldRest];
FigFallThroughError[Self_Symbol,Expr_]:=Module[
{},
If[
Count[Hold[Expr],Null,{2}]>0,
FigError[Self,"figargsnull",HoldForm[Expr]],
FigError[Self,"figargs",HoldForm[Expr]]
]
];
DeclareFigFallThroughError[f_Symbol]:=(Expr:HoldPattern[f[___]]:=FigFallThroughError[f,Expr]);
(*Message suppression*)
(*SuppressMessage is a scoping structure which temporarily suppresses a specified message while evaluating an expression, without affecting the global On/Off status of the message.*)
SetAttributes[SuppressMessage,HoldAll];
SuppressMessage[MessageID_,Body_]:=Module[
{WasOn,EvaluatedBody,Aborted},
AbortProtect[
(* record prior message status *)
WasOn=Switch[
Head[MessageID],
String|MessageName,True,
$Off,False
];
(* evaluate body with message disabled *)
Off[MessageID];
Aborted=False;
CheckAbort[
EvaluatedBody=Body,
Aborted=True
];
(* restore message status *)
If[WasOn,On[MessageID]];
];
(* return value *)
(* passes through abort, and also explicitly returns $Aborted in case Abort[] is suppressed *)
If[Aborted,Abort[];$Aborted,EvaluatedBody]
];
(*Option and parameter validation*)
(*Option check against pattern*)
General::figbadopt="Option `1` has invalid value `2`.";
FigCheckOption[Caller:((_Object)|(_Symbol)),OptionName_Symbol,TestPattern_,OptionList_List]:=Module[
{},
(*
If[
OptionName\[Equal]Width,
Print["value ",(OptionName/.OptionList)," pattern ",FullForm[TestPattern]," match ",MatchQ[(OptionName/.OptionList),TestPattern]];
];
*)
If[
!MatchQ[(OptionName/.OptionList),TestPattern],
FigError[Caller,"figbadopt",OptionName,(OptionName/.OptionList)]
]
];
FigCheckOption[SpecialMode:MakeAnchor,Caller:((_Object)|(_Symbol)),OptionName_Symbol,TestPattern_,OptionList_List]:=Module[
{},
If[
!MatchQ[(OptionName/.OptionList),TestPattern],
FigError[SpecialMode,Caller,"figbadopt",OptionName,(OptionName/.OptionList)]
]
];
(*Value check against pattern*)
General::figbadvalue="The `1` has an invalid value `2`.";
FigCheckValue[Caller:((_Object)|(_Symbol)),Value_,TestPattern_,Description_String]:=Module[
{},
If[
!MatchQ[Value,TestPattern],
FigError[Caller,"figbadvalue",Description,Value]
]
];
General::figbadvaluelist="One of the `1` has an invalid value `2`.";
FigCheckValueList[Caller:((_Object)|(_Symbol)),ValueList_List,TestPattern_,Description_String]:=Module[
{Value},
Do[
If[
!MatchQ[Value,TestPattern],
FigError[Caller,"figbadvaluelist",Description,Value]
],
{Value,ValueList}
]
];
(*End package*)
(*Exit private context*)
End[];
(*Exit package context*)
Protect[Evaluate[$Context<>"*"]];
Unprotect[Evaluate[$Context<>"$*"]];
EndPackage[];