1 | TMGSTUTL ;TMG/kst/String Utilities and Library ;03/25/06,5/10/10 ; 5/19/10 5:01pm
|
---|
2 | ;;1.0;TMG-LIB;**1**;09/01/05
|
---|
3 |
|
---|
4 | ;"TMG STRING UTILITIES
|
---|
5 |
|
---|
6 | ;"=======================================================================
|
---|
7 | ;" API -- Public Functions.
|
---|
8 | ;"=======================================================================
|
---|
9 | ;"CleaveToArray^TMGSTUTL(Text,Divider,Array)
|
---|
10 | ;"CatArray(Words,i1,i2,DivChr) -- return concat array from index1 to index2
|
---|
11 | ;"CleaveStr^TMGSTUTL(Text,Divider,PartB)
|
---|
12 | ;"SplitStr^TMGSTUTL(Text,Width,PartB)
|
---|
13 | ;"SetStrLen^TMGSTUTL(Text,Width)
|
---|
14 | ;"$$NestSplit^TMGSTUTL(Text,OpenBracket,CloseBracket,SBefore,S,SAfter)
|
---|
15 | ;"$$Substitute^TMGSTUTL(S,Match,NewValue)
|
---|
16 | ;"$$FormatArray^TMGSTUTL(InArray,OutArray,Divider)
|
---|
17 | ;"$$Trim^TMGSTUTL(S,TrimCh) ; --> or use $$TRIM^XLFSTR
|
---|
18 | ;"$$TrimL^TMGSTUTL(S,TrimCh)
|
---|
19 | ;"$$TrimR^TMGSTUTL(S,TrimCh)
|
---|
20 | ;"$$TrimRType^TMGSTUTL(S,type)
|
---|
21 | ;"$$NumLWS^TMGSTUTL(S)
|
---|
22 | ;"$$MakeWS^TMGSTUTL(n)
|
---|
23 | ;"WordWrapArray^TMGSTUTL(.Array,Width,SpecialIndent)
|
---|
24 | ;"SplitLine^TMGSTUTL(s,.LineArray,Width)
|
---|
25 | ;"WriteWP^TMGSTUTL(NodeRef)
|
---|
26 | ;"$$LPad^TMGSTUTL(S,width) ;"NOTE: should use XLFSTR fn below
|
---|
27 | ;"$$RPad^TMGSTUTL(S,width) ;"NOTE: should use XLFSTR fn below
|
---|
28 | ;"$$Center^TMGSTUTL(S,width) ;"NOTE: should use XLFSTR fn below
|
---|
29 | ;"$$Clip^TMGSTUTL(S,width)
|
---|
30 | ;"$$STRB2H^TMGSTUTL(s,F) Convert a string to hex characters
|
---|
31 | ;"$$CapWords^TMGSTUTL(S,Divider) ;"capitalize the first character of each word in a string
|
---|
32 | ;"$$LinuxStr^TMGSTUTL(S) ;"Convert string to a valid linux filename
|
---|
33 | ;"StrToWP^TMGSTUTL(s,pArray,width,DivCh,InitLine) ;"wrap long string into a WP array
|
---|
34 | ;"$$WPToStr^TMGSTUTL(pArray,DivCh,MaxLen,InitLine)
|
---|
35 | ;"Comp2Strs(s1,s2) -- compare two strings and assign an arbritrary score to their similarity
|
---|
36 | ;"$$PosNum(s,[Num],LeadingSpace) -- return position of a number in a string
|
---|
37 | ;"IsNumeric(s) -- deterimine if word s is a numeric
|
---|
38 | ;"ScrubNumeric(s) -- remove numeric words from a sentence
|
---|
39 | ;"Pos(subStr,s,count) -- return the beginning position of subStr in s
|
---|
40 | ;"DiffPos(s1,s2) -- Return the position of the first difference between s1 and s2
|
---|
41 | ;"DiffWords(Words1,Words2) -- Return index of first different word between Words arrays
|
---|
42 | ;"SimStr(s1,p1,s2,p2) -- return matching string in s1 and s2, starting at position p1,p2
|
---|
43 | ;"SimWord(Words1,p1,Words2,p2) -- return the matching words in both words array 1 and 2, starting
|
---|
44 | ;" at word positions p1 and p2.
|
---|
45 | ;"SimPos(s1,s2) -- return the first position that two strings are similar.
|
---|
46 | ;"SimWPos(Words1,Words2,DivStr,p1,p2,MatchStr) -- return the first position that two word arrays
|
---|
47 | ;" are similar. This means the first index in Words array 1 that matches to words in Words array 2.
|
---|
48 | ;"DiffStr(s1,s2,DivChr) -- Return how s1 differs from s2.
|
---|
49 | ;"CatArray(Words,i1,i2,DivChr) -- return concat array from index1 to index2
|
---|
50 | ;"$$QtProtect(s) -- Protects quotes by converting all quotes to double quotes (" --> "")
|
---|
51 | ;"$$QTPROTECT(S) -- Same as $$QtProtect(s)
|
---|
52 | ;"$$InQt(s,Pos) -- return if a character at position P is inside quotes in s
|
---|
53 | ;"$$HNQTSUB(s,SubStr) --Same as $$HasNonQtSub
|
---|
54 | ;"$$HasNonQtSub(s,SubStr) -- return if string s contains SubStr, but not inside quotes.
|
---|
55 | ;"$$GetWord(s,Pos,OpenDiv,CloseDiv) -- extract a word from a sentance, bounded by OpenDiv,CloseDiv
|
---|
56 | ;"$$MATCHXTR(s,DivCh,Group,Map) -- Same as $$MatchXtract
|
---|
57 | ;"$$MatchXtract(s,DivCh,Group,Map) -- extract a string bounded by DivCh, honoring matching encapsulators
|
---|
58 | ;"MapMatch(s,Map) -- map a string with nested braces, parentheses etc (encapsulators)
|
---|
59 | ;"$$CmdChStrip(s) -- Strips all characters < #32 from string.
|
---|
60 | ;"$$StrBounds(s,p) -- return position of end of string
|
---|
61 | ;"NonWhite(s,p) -- return index of first non-whitespace character
|
---|
62 | ;"Pad2Pos(Pos,ch) -- return a padding string from current $X up to Pos, using ch
|
---|
63 | ;"HTML2TXT(Array) -- Take WP array that is HTML formatted, and strip <P>, and return in a format of 1 line per array node.
|
---|
64 | ;"TrimTags(lineS) -- cut out HTML tags (e.g. <...>) from lineS, however, <no data> is protected
|
---|
65 | ;"$$IsHTML(IEN8925) --specify if the text held in the REPORT TEXT field in record IEN8925 is HTML markup
|
---|
66 |
|
---|
67 | ;"=======================================================================
|
---|
68 | ;"Dependancies
|
---|
69 | ;" uses TMGDEBUG for debug messaging.
|
---|
70 | ;"=======================================================================
|
---|
71 | ;"=======================================================================
|
---|
72 |
|
---|
73 | ;"------------------------------------------------------------------------
|
---|
74 | ;"FYI, String functions in XLFSTR module:
|
---|
75 | ;"------------------------------------------------------------------------
|
---|
76 | ;"$$CJ^XLFSTR(s,i[,p]) -- Returns a center-justified string
|
---|
77 | ;" s=string, i=field size, p(optional)=pad character
|
---|
78 | ;"$$LJ^XLFSTR(s,i[,p]) -- Returns a left-justified string
|
---|
79 | ;" s=string, i=field size, p(optional)=pad character
|
---|
80 | ;"$$RJ^XLFSTR(s,i[,p]) -- Returns a right-justified string
|
---|
81 | ;" s=string, i=field size, p(optional)=pad character
|
---|
82 | ;"$$INVERT^XLFSTR(s) -- returns an inverted string (i.e. "ABC"-->"CBA")
|
---|
83 | ;"$$LOW^XLFSTR(s) -- returns string with all letters converted to lower-case
|
---|
84 | ;"$$UP^XLFSTR(s) -- returns string with all letters converted to upper-case
|
---|
85 | ;"$$TRIM^XLFSTR(s,[LRFlags],[char])
|
---|
86 | ;"$$REPEAT^XLFSTR(s,Count) -- returns a string that is a repeat of s Count times
|
---|
87 | ;"$$REPLACE^XLFSTR(s,.spec) -- Uses a multi-character $TRanslate to return a
|
---|
88 | ;" string with the specified string replaced
|
---|
89 | ;" s=input string, spec=array passed by reference
|
---|
90 | ;" spec format:
|
---|
91 | ;" spec("Any_Search_String")="Replacement_String"
|
---|
92 | ;"$$STRIP^XLFSTR(s,Char) -- returns string striped of all instances of Char
|
---|
93 |
|
---|
94 | ;"=======================================================================
|
---|
95 |
|
---|
96 | CleaveToArray(Text,Divider,Array,InitIndex)
|
---|
97 | ;"Purpose: To take a string, delineated by 'divider' and
|
---|
98 | ;" to split it up into all its parts, putting each part
|
---|
99 | ;" into an array. e.g.:
|
---|
100 | ;" This/Is/A/Test, with '/' divider would result in
|
---|
101 | ;" Array(1)="This"
|
---|
102 | ;" Array(2)="Is"
|
---|
103 | ;" Array(3)="A"
|
---|
104 | ;" Array(4)="Test"
|
---|
105 | ;" Array(cMaxNode)=4 ;cMaxNode="MAXNODE"
|
---|
106 | ;"Input: Text - the input string -- should NOT be passed by reference.
|
---|
107 | ;" Divider - the delineating string
|
---|
108 | ;" Array - The array to receive output **SHOULD BE PASSED BY REFERENCE.
|
---|
109 | ;" InitIndex - OPTIONAL -- The index of the array to start with, i.e. 0 or 1. Default=1
|
---|
110 | ;"Output: Array is changed, as outlined above
|
---|
111 | ;"Result: none
|
---|
112 | ;"Notes: Note -- Text is NOT changed (unless passed by reference, in
|
---|
113 | ;" which case the next to the last piece is put into Text)
|
---|
114 | ;" Array is killed, the filled with data **ONLY** IF DIVISIONS FOUND
|
---|
115 | ;" Limit of 256 nodes
|
---|
116 | ;" if cMaxNode is not defined, "MAXNODE" will be used
|
---|
117 |
|
---|
118 | set DBIndent=$get(DBIndent,0)
|
---|
119 | do DebugEntry^TMGDEBUG(.DBIndent,"CleaveToArray")
|
---|
120 |
|
---|
121 | set InitIndex=$get(InitIndex,1)
|
---|
122 | new PartB
|
---|
123 | new count set count=InitIndex
|
---|
124 | set cMaxNode=$get(cMaxNode,"MAXNODE")
|
---|
125 |
|
---|
126 | kill Array ;"Clear out any old data
|
---|
127 |
|
---|
128 | C2ArLoop
|
---|
129 | if '(Text[Divider) do goto C2ArDone
|
---|
130 | . set Array(count)=Text ;"put it all into first line.
|
---|
131 | . set Array(cMaxNode)=1
|
---|
132 | do CleaveStr(.Text,Divider,.PartB)
|
---|
133 | set Array(count)=Text
|
---|
134 | set Array(cMaxNode)=count
|
---|
135 | set count=count+1
|
---|
136 | if '(PartB[Divider) do goto C2ArDone
|
---|
137 | . set Array(count)=PartB
|
---|
138 | . set Array(cMaxNode)=count
|
---|
139 | else do goto C2ArLoop
|
---|
140 | . set Text=$get(PartB)
|
---|
141 | . set PartB=""
|
---|
142 |
|
---|
143 | C2ArDone
|
---|
144 | do DebugExit^TMGDEBUG(.DBIndent,"CleaveToArray")
|
---|
145 | quit
|
---|
146 |
|
---|
147 |
|
---|
148 | CleaveStr(Text,Divider,PartB)
|
---|
149 | ;"Purpse: To take a string, delineated by 'Divider'
|
---|
150 | ;" and to split it into two parts: Text and PartB
|
---|
151 | ;" e.g. Text="Hello\nThere"
|
---|
152 | ;" Divider="\n"
|
---|
153 | ;" Function will result in: Text="Hello", PartB="There"
|
---|
154 | ;"Input: Text - the input string **SHOULD BE PASSED BY REFERENCE.
|
---|
155 | ;" Divider - the delineating string
|
---|
156 | ;" PartB - the string to get second part **SHOULD BE PASSED BY REFERENCE.
|
---|
157 | ;"Output: Text and PartB will be changed
|
---|
158 | ;" Function will result in: Text="Hello", PartB="There"
|
---|
159 | ;"Result: none
|
---|
160 |
|
---|
161 | set DBIndent=$get(DBIndent,0)
|
---|
162 | do DebugEntry^TMGDEBUG(.DBIndent,"CleaveStr")
|
---|
163 |
|
---|
164 | do DebugMsg^TMGDEBUG(DBIndent,"Text=",Text)
|
---|
165 |
|
---|
166 | if '$data(Text) goto CSDone
|
---|
167 | if '$Data(Divider) goto CSDone
|
---|
168 | set PartB=""
|
---|
169 |
|
---|
170 | new PartA
|
---|
171 |
|
---|
172 | if Text[Divider do
|
---|
173 | . set PartA=$piece(Text,Divider,1)
|
---|
174 | . set PartB=$piece(Text,Divider,2,256)
|
---|
175 | . set Text=PartA
|
---|
176 |
|
---|
177 | do DebugMsg^TMGDEBUG(DBIndent,"After Processing, Text='",Text,"', and PartB='",PartB,"'")
|
---|
178 | CSDone
|
---|
179 | do DebugExit^TMGDEBUG(.DBIndent,"CleaveStr")
|
---|
180 | quit
|
---|
181 |
|
---|
182 |
|
---|
183 | SplitStr(Text,Width,PartB)
|
---|
184 | ;"PUBLIC FUNCTION
|
---|
185 | ;"Purpose: To a string into two parts. The first part will fit within 'Width'
|
---|
186 | ;" the second part is what is left over
|
---|
187 | ;" The split will be inteligent, so words are not divided (splits at a space)
|
---|
188 | ;"Input: Text = input text. **Should be passed by reference
|
---|
189 | ;" Width = the constraining width
|
---|
190 | ;" PartB = the left over part. **Should be passed by reference
|
---|
191 | ;"output: Text and PartB are modified
|
---|
192 | ;"result: none.
|
---|
193 |
|
---|
194 | new Len
|
---|
195 | set Width=$get(Width,80)
|
---|
196 | new SpaceFound set SpaceFound=0
|
---|
197 | new SplitPoint set SplitPoint=Width
|
---|
198 | set Text=$get(Text)
|
---|
199 | set PartB=""
|
---|
200 |
|
---|
201 | set Len=$length(Text)
|
---|
202 | if Len>Width do
|
---|
203 | . new Ch
|
---|
204 | . for SplitPoint=SplitPoint:-1:1 do quit:SpaceFound
|
---|
205 | . . set Ch=$extract(Text,SplitPoint,SplitPoint)
|
---|
206 | . . set SpaceFound=(Ch=" ")
|
---|
207 | . if 'SpaceFound set SplitPoint=Width
|
---|
208 | . set s1=$extract(Text,1,SplitPoint)
|
---|
209 | . set PartB=$extract(Text,SplitPoint+1,1024) ;"max String length=1024
|
---|
210 | . set Text=s1
|
---|
211 | else do
|
---|
212 |
|
---|
213 | quit
|
---|
214 |
|
---|
215 |
|
---|
216 |
|
---|
217 | SetStrLen(Text,Width)
|
---|
218 | ;"PUBLIC FUNCTION
|
---|
219 | ;"Purpose: To make string exactly Width in length
|
---|
220 | ;" Shorten as needed, or pad with terminal spaces as needed.
|
---|
221 | ;"Input: Text -- should be passed as reference. This is string to alter.
|
---|
222 | ;" Width -- the desired width
|
---|
223 | ;"Results: none.
|
---|
224 |
|
---|
225 | set Text=$get(Text)
|
---|
226 | set Width=$get(Width,80)
|
---|
227 | new result set result=Text
|
---|
228 | new i,Len
|
---|
229 |
|
---|
230 | set Len=$length(result)
|
---|
231 | if Len>Width do
|
---|
232 | . set result=$extract(result,1,Width)
|
---|
233 | else if Len<Width do
|
---|
234 | . for i=1:1:(Width-Len) set result=result_" "
|
---|
235 |
|
---|
236 | set Text=result ;"pass back changes
|
---|
237 |
|
---|
238 | quit
|
---|
239 |
|
---|
240 |
|
---|
241 | NestSplit(Text,OpenBracket,CloseBracket,SBefore,S,SAfter)
|
---|
242 | ;"PUBLIC FUNCTION
|
---|
243 | ;"Purpose: To take a string in this format:
|
---|
244 | ;" Text='a big black {{Data.Section[{{MVar.Num}}]}} chased me'
|
---|
245 | ;" OpenBracket='{{'
|
---|
246 | ;" CloseBracket='}}'
|
---|
247 | ;" and return:
|
---|
248 | ;" SBefore='a big black {{Data.Section['
|
---|
249 | ;" S='MVar.Num
|
---|
250 | ;" SAfter=']}} chased me'
|
---|
251 | ;" Notice that this function will return the INNER-MOST text inside the brackets pair
|
---|
252 | ;" Note: if multiple sets of brackets exist in the string, like this:
|
---|
253 | ;" 'I am a {{MVar.Person}} who loves {{MVar.Food}} every day.
|
---|
254 | ;" Then the LAST set (i.e. MVar.Food) will be returned in S
|
---|
255 | ;"
|
---|
256 | ;"Input:Text -- the string to operate on
|
---|
257 | ;" OpenBracket -- string with opening brackets (i.e. '(','{', '{{' etc.)
|
---|
258 | ;" CloseBracket -- string with close brackets (i.e. ')','}','}}' etc.)
|
---|
259 | ;" SBefore -- SHOULD BE PASSED BY REFERENCE... to receive results.
|
---|
260 | ;" S -- SHOULD BE PASSED BY REFERENCE... to receive results.
|
---|
261 | ;" SAfter -- SHOULD BE PASSED BY REFERENCE... to receive results.
|
---|
262 | ;"Output: SBefore -- returns all text up to innermost opening brackets, or "" if none
|
---|
263 | ;" S -- returns text INSIDE innermost brackets -- with brackets REMOVED, or "" if none
|
---|
264 | ;" SAfter -- returns all text after innermost opening brackets, or "" if none
|
---|
265 | ;" Text is NOT changed
|
---|
266 | ;" NOTE: Above vars must be passed by reference to recieve results.
|
---|
267 | ;"Results: 1=valid results returned in output vars.
|
---|
268 | ;" 0=No text found inside brackets, so output vars empty.
|
---|
269 |
|
---|
270 | set SBefore="",S="",SAfter=""
|
---|
271 | new Result set Result=0
|
---|
272 |
|
---|
273 | ;"do DebugEntry^TMGDEBUG(.DBIndent,"NestSplit")
|
---|
274 |
|
---|
275 | if $data(Text)#10=0 goto QNSp
|
---|
276 | ;"do DebugMsg^TMGDEBUG(DBIndent,"Looking at '",Text,"'")
|
---|
277 | if ($data(OpenBracket)#10=0)!($data(CloseBracket)#10=0) goto QNSp
|
---|
278 | if '((Text[OpenBracket)&(Text[CloseBracket)) goto QNSp
|
---|
279 |
|
---|
280 |
|
---|
281 | ;"First we need to get the text after LAST instance of OpenBracket
|
---|
282 | ;"i.e. 'MVar.Num}}]}}' chased m from 'a big black {{Data.Section[{{MVar.Num}}]}} chased me'
|
---|
283 | new i set i=2
|
---|
284 | new part set part=""
|
---|
285 | new temp set temp=""
|
---|
286 | NSL1 set temp=$piece(Text,OpenBracket,i)
|
---|
287 | if temp'="" do goto NSL1
|
---|
288 | . set part=temp
|
---|
289 | . set SBefore=$piece(Text,OpenBracket,1,i-1)
|
---|
290 | . set i=i+1
|
---|
291 |
|
---|
292 | ;"do DebugMsg^TMGDEBUG(DBIndent,"First part is: ",SBefore)
|
---|
293 |
|
---|
294 | ;"Now we find the text before the FIRST instance of CloseBracket
|
---|
295 | ;"i.e. 'MVar.Num' from 'MVar.Num}}]}} chased me'
|
---|
296 | ;"do DebugMsg^TMGDEBUG(DBIndent,"part=",part)
|
---|
297 | set S=$piece(part,CloseBracket,1)
|
---|
298 | set SAfter=$piece(part,CloseBracket,2,128)
|
---|
299 |
|
---|
300 | ;"do DebugMsg^TMGDEBUG(DBIndent,"Main result is :",S)
|
---|
301 | ;"do DebugMsg^TMGDEBUG(DBIndent,"Part after result is: ",SAfter)
|
---|
302 |
|
---|
303 | ;"If we got here, we are successful
|
---|
304 | set Result=1
|
---|
305 |
|
---|
306 | QNSp
|
---|
307 | ;"do DebugExit^TMGDEBUG(.DBIndent,"NestSplit")
|
---|
308 |
|
---|
309 | quit Result
|
---|
310 |
|
---|
311 |
|
---|
312 | Substitute(S,Match,NewValue)
|
---|
313 | ;"PUBLIC FUNCTION
|
---|
314 | ;"Purpose: to look for all instances of Match in S, and replace with NewValue
|
---|
315 | ;"Input: S - string to alter. Altered if passed by reference
|
---|
316 | ;" Match -- the sequence to look for, i.e. '##'
|
---|
317 | ;" NewValue -- what to replace Match with, i.e. '$$'
|
---|
318 | ;"Note: This is different than $translate, as follows
|
---|
319 | ;" $translate("ABC###DEF","###","$") --> "ABC$$$DEF"
|
---|
320 | ;" Substitute("ABC###DEF","###","$") --> "ABC$DEF"
|
---|
321 | ;"Result: returns altered string (if any alterations indicated)
|
---|
322 | ;"Output: S is altered, if passed by reference.
|
---|
323 |
|
---|
324 | new spec
|
---|
325 | set spec($get(Match))=$get(NewValue)
|
---|
326 | set S=$$REPLACE^XLFSTR(S,.spec)
|
---|
327 |
|
---|
328 | quit S
|
---|
329 |
|
---|
330 |
|
---|
331 | FormatArray(InArray,OutArray,Divider)
|
---|
332 | ;"PUBLIC FUNCTION
|
---|
333 | ;"Purpose: The XML parser does not recognize whitespace, or end-of-line
|
---|
334 | ;" characters. Thus many lines get lumped together. However, if there
|
---|
335 | ;" is a significant amount of text, then the parser will put the text into
|
---|
336 | ;" several lines (when get attrib text called etc.)
|
---|
337 | ;" SO, this function is to take an array composed of input lines (each
|
---|
338 | ;" with multiple sublines clumped together), and format it such that each
|
---|
339 | ;" line is separated in the array.
|
---|
340 | ;" e.g. Take this input array"
|
---|
341 | ;" InArray(cText,1)="line one\nline two\nline three\n
|
---|
342 | ;" InArray(cText,2)="line four\nline five\nline six\n
|
---|
343 | ;" and convert to:
|
---|
344 | ;" OutArray(1)="line one"
|
---|
345 | ;" OutArray(2)="line two"
|
---|
346 | ;" OutArray(3)="line three"
|
---|
347 | ;" OutArray(4)="line four"
|
---|
348 | ;" OutArray(5)="line five"
|
---|
349 | ;" OutArray(6)="line six"
|
---|
350 | ;"Input: InArray, best if passed by reference (faster) -- see example above
|
---|
351 | ;" Note: expected to be in format: InArray(cText,n)
|
---|
352 | ;" OutArray, must be passed by reference-- see example above
|
---|
353 | ;" Divider: the character(s) that divides lines ("\n" in this example)
|
---|
354 | ;"Note: It is expected that InArray will be index by integers (i.e. 1, 2, 3)
|
---|
355 | ;" And this should be the case, as that is how XML functions pass back.
|
---|
356 | ;" Limit of 256 separate lines on any one InArray line
|
---|
357 | ;"Output: OutArray is set, any prior data is killed
|
---|
358 | ;"result: 1=OK to continue, 0=abort
|
---|
359 |
|
---|
360 | set DEBUG=$get(DEBUG,0)
|
---|
361 | set cOKToCont=$get(cOKToCont,1)
|
---|
362 | set cAbort=$get(cAbort,0)
|
---|
363 |
|
---|
364 | if DEBUG>0 do DebugEntry^TMGDEBUG(.DBIndent,"FormatArray")
|
---|
365 |
|
---|
366 | new result set result=cOKToCont
|
---|
367 | new InIndex
|
---|
368 | new OutIndex set OutIndex=1
|
---|
369 | new TempArray
|
---|
370 | new Done
|
---|
371 |
|
---|
372 | kill OutArray ;"remove any prior data
|
---|
373 |
|
---|
374 | if DEBUG>0 do DebugMsg^TMGDEBUG(DBIndent,"Input array:")
|
---|
375 | if DEBUG do ArrayDump^TMGDEBUG("InArray")
|
---|
376 |
|
---|
377 | if $data(Divider)=0 do goto FADone
|
---|
378 | . set result=cAbort
|
---|
379 |
|
---|
380 | set Done=0
|
---|
381 | for InIndex=1:1 do quit:Done
|
---|
382 | . if $data(InArray(cText,InIndex))=0 set Done=1 quit
|
---|
383 | . if DEBUG>0 do DebugMsg^TMGDEBUG(DBIndent,"Converting line: ",InArray(cText,InIndex))
|
---|
384 | . do CleaveToArray^TMGSTUTL(InArray(cText,InIndex),Divider,.TempArray,OutIndex)
|
---|
385 | . if DEBUG>0 do DebugMsg^TMGDEBUG(DBIndent,"Resulting temp array:")
|
---|
386 | . if DEBUG do ArrayDump^TMGDEBUG("TempArray")
|
---|
387 | . set OutIndex=TempArray(cMaxNode)+1
|
---|
388 | . kill TempArray(cMaxNode)
|
---|
389 | . merge OutArray=TempArray
|
---|
390 | . if DEBUG>0 do DebugMsg^TMGDEBUG(DBIndent,"OutArray so far:")
|
---|
391 | . if DEBUG do ArrayDump^TMGDEBUG("OutArray")
|
---|
392 |
|
---|
393 | FADone
|
---|
394 | if DEBUG>0 do DebugExit^TMGDEBUG(.DBIndent,"FormatArray")
|
---|
395 | quit result
|
---|
396 |
|
---|
397 |
|
---|
398 |
|
---|
399 | TrimL(S,TrimCh)
|
---|
400 | ;"Purpose: To a trip a string of leading white space
|
---|
401 | ;" i.e. convert " hello" into "hello"
|
---|
402 | ;"Input: S -- the string to convert. Won't be changed if passed by reference
|
---|
403 | ;" TrimCh -- OPTIONAL: Charachter to trim. Default is " "
|
---|
404 | ;"Results: returns modified string
|
---|
405 | ;"Note: processing limitation is string length=1024
|
---|
406 |
|
---|
407 | set DEBUG=$get(DEBUG,0)
|
---|
408 | set cOKToCont=$get(cOKToCont,1)
|
---|
409 | set cAbort=$get(cAbort,0)
|
---|
410 | set TrimCh=$get(TrimCh," ")
|
---|
411 |
|
---|
412 | new result set result=$get(S)
|
---|
413 | new Ch set Ch=""
|
---|
414 | for do quit:(Ch'=TrimCh)
|
---|
415 | . set Ch=$extract(result,1,1)
|
---|
416 | . if Ch=TrimCh set result=$extract(result,2,1024)
|
---|
417 |
|
---|
418 | quit result
|
---|
419 |
|
---|
420 |
|
---|
421 | TrimR(S,TrimCh)
|
---|
422 | ;"Purpose: To a trip a string of trailing white space
|
---|
423 | ;" i.e. convert "hello " into "hello"
|
---|
424 | ;"Input: S -- the string to convert. Won't be changed if passed by reference
|
---|
425 | ;" TrimCh -- OPTIONAL: Charachter to trim. Default is " "
|
---|
426 | ;"Results: returns modified string
|
---|
427 | ;"Note: processing limitation is string length=1024
|
---|
428 |
|
---|
429 | set DEBUG=$get(DEBUG,0)
|
---|
430 | set cOKToCont=$get(cOKToCont,1)
|
---|
431 | set cAbort=$get(cAbort,0)
|
---|
432 | set TrimCh=$get(TrimCh," ")
|
---|
433 |
|
---|
434 | if DEBUG>0 do DebugEntry^TMGDEBUG(.DBIndent,"TrimR")
|
---|
435 |
|
---|
436 | new result set result=$get(S)
|
---|
437 | new Ch set Ch=""
|
---|
438 | new L
|
---|
439 |
|
---|
440 | for do quit:(Ch'=TrimCh)
|
---|
441 | . set L=$length(result)
|
---|
442 | . set Ch=$extract(result,L,L)
|
---|
443 | . if Ch=TrimCh do
|
---|
444 | . . set result=$extract(result,1,L-1)
|
---|
445 |
|
---|
446 | if DEBUG>0 do DebugExit^TMGDEBUG(.DBIndent,"TrimR")
|
---|
447 | quit result
|
---|
448 |
|
---|
449 | Trim(S,TrimCh)
|
---|
450 | ;"Purpose: To a trip a string of leading and trailing white space
|
---|
451 | ;" i.e. convert " hello " into "hello"
|
---|
452 | ;"Input: S -- the string to convert. Won't be changed if passed by reference
|
---|
453 | ;" TrimCh -- OPTIONAL: Charachter to trim. Default is " "
|
---|
454 | ;"Results: returns modified string
|
---|
455 | ;"Note: processing limitation is string length=1024
|
---|
456 |
|
---|
457 | ;"NOTE: this function could be replaced with $$TRIM^XLFSTR
|
---|
458 |
|
---|
459 | set DEBUG=$get(DEBUG,0)
|
---|
460 | set cOKToCont=$get(cOKToCont,1)
|
---|
461 | set cAbort=$get(cAbort,0)
|
---|
462 | set TrimCh=$get(TrimCh," ")
|
---|
463 |
|
---|
464 | if DEBUG>0 do DebugEntry^TMGDEBUG(.DBIndent,"Trim")
|
---|
465 |
|
---|
466 | new result set result=$get(S)
|
---|
467 | set result=$$TrimL(.result,TrimCh)
|
---|
468 | set result=$$TrimR(.result,TrimCh)
|
---|
469 |
|
---|
470 | if DEBUG>0 do DebugExit^TMGDEBUG(.DBIndent,"Trim")
|
---|
471 | quit result
|
---|
472 |
|
---|
473 | TrimRType(S,type)
|
---|
474 | ;"Scope: PUBLIC FUNCTION
|
---|
475 | ;"Purpose: trim characters on the right of the string of a specified type.
|
---|
476 | ;" Goal, to be able to distinguish between numbers and strings.
|
---|
477 | ;" i.e. "1234<=" --> "1234" by trimming strings
|
---|
478 | ;"Input: S -- The string to work on
|
---|
479 | ;" type -- the type of characters to TRIM: N for numbers,C for non-numbers (characters)
|
---|
480 | ;"Results : modified string
|
---|
481 |
|
---|
482 | set tempS=$get(S)
|
---|
483 | set type=$$UP^XLFSTR($get(type)) goto:(type="") TRTDone
|
---|
484 | new done set done=0
|
---|
485 | for quit:(tempS="")!done do
|
---|
486 | . new c set c=$extract(tempS,$length(tempS))
|
---|
487 | . new cType set cType="C"
|
---|
488 | . if +c=c set cType="N"
|
---|
489 | . if type["N" do
|
---|
490 | . . if cType="N" set tempS=$extract(tempS,1,$length(tempS)-1) quit
|
---|
491 | . . set done=1
|
---|
492 | . else if type["C" do
|
---|
493 | . . if cType="C" set tempS=$extract(tempS,1,$length(tempS)-1) quit
|
---|
494 | . . set done=1
|
---|
495 | . else set done=1
|
---|
496 |
|
---|
497 | TRTDone quit tempS
|
---|
498 |
|
---|
499 | NumLWS(S)
|
---|
500 | ;"Scope: PUBLIC FUNCTION
|
---|
501 | ;":Purpose: To count the number of white space characters on the left
|
---|
502 | ;" side of the string
|
---|
503 |
|
---|
504 | new result set result=0
|
---|
505 | new i,ch
|
---|
506 | set S=$get(S)
|
---|
507 |
|
---|
508 | for i=1:1:$length(S) do quit:(ch'=" ")
|
---|
509 | . set ch=$extract(S,i,i)
|
---|
510 | . if ch=" " set result=result+1
|
---|
511 |
|
---|
512 | quit result
|
---|
513 |
|
---|
514 |
|
---|
515 | MakeWS(n)
|
---|
516 | ;"Scope: PUBLIC FUNCTION
|
---|
517 | ;"Purpose: Return a whitespace string that is n characters long
|
---|
518 |
|
---|
519 | new result set result=""
|
---|
520 | set n=$get(n,0)
|
---|
521 | if n'>0 goto MWSDone
|
---|
522 |
|
---|
523 | new i
|
---|
524 | for i=1:1:n set result=result_" "
|
---|
525 |
|
---|
526 | MWSDone
|
---|
527 | quit result
|
---|
528 |
|
---|
529 |
|
---|
530 | WordWrapArray(Array,Width,SpecialIndent)
|
---|
531 | ;"Scope: PUBLIC FUNCTION
|
---|
532 | ;"Purpose: To take an array and perform word wrapping such that
|
---|
533 | ;" no line is longer than Width.
|
---|
534 | ;" This function is really designed for reformatting a Fileman WP field
|
---|
535 | ;"Input: Array MUST BE PASSED BY REFERENCE. This contains the array
|
---|
536 | ;" to be reformatted. Changes will be made to this array.
|
---|
537 | ;" It is expected that Array will be in this format:
|
---|
538 | ;" Array(1)="Some text on the first line."
|
---|
539 | ;" Array(2)="Some text on the second line."
|
---|
540 | ;" Array(3)="Some text on the third line."
|
---|
541 | ;" Array(4)="Some text on the fourth line."
|
---|
542 | ;" or
|
---|
543 | ;" Array(1,0)="Some text on the first line."
|
---|
544 | ;" Array(2,0)="Some text on the second line."
|
---|
545 | ;" Array(3,0)="Some text on the third line."
|
---|
546 | ;" Array(4,0)="Some text on the fourth line."
|
---|
547 | ;" Width -- the limit on the length of any line. Default value=70
|
---|
548 | ;" SpecialIndent : if 1, then wrapping is done like this:
|
---|
549 | ;" " This is a very long line......"
|
---|
550 | ;" will be wrapped like this:
|
---|
551 | ;" " This is a very
|
---|
552 | ;" " long line ...
|
---|
553 | ;" Notice that the leading space is copied subsequent line.
|
---|
554 | ;" Also, a line like this:
|
---|
555 | ;" " 1. Here is the beginning of a paragraph that is very long..."
|
---|
556 | ;" will be wrapped like this:
|
---|
557 | ;" " 1. Here is the beginning of a paragraph
|
---|
558 | ;" " that is very long..."
|
---|
559 | ;" Notice that a pattern '#. ' causes the wrapping to match the start of
|
---|
560 | ;" of the text on the line above.
|
---|
561 | ;" The exact rules for matching this are as follows:
|
---|
562 | ;" (FirstWord?.N1".")!(FirstWord?1.3E1".")
|
---|
563 | ;" i.e. any number of digits, followed by "."
|
---|
564 | ;" OR 1-4 all upper-case characters followed by a "."
|
---|
565 | ;" This will allow "VIII. " pattern but not "viii. "
|
---|
566 | ;" HOWEVER, might get confused with a word, like "NOTE. "
|
---|
567 | ;"
|
---|
568 | ;" This, below, is not dependant on SpecialIndent setting
|
---|
569 | ;" Also, because some of the lines have already partly wrapped, like this:
|
---|
570 | ;" " 1. Here is the beginning of a paragraph that is very long..."
|
---|
571 | ;" "and this is a line that has already wrapped.
|
---|
572 | ;" So when the first line is wrapped, it would look like this:
|
---|
573 | ;" " 1. Here is the beginning of a paragraph
|
---|
574 | ;" " that is very long..."
|
---|
575 | ;" "and this is a line that has already wrapped.
|
---|
576 | ;" But is should look like this:
|
---|
577 | ;" " 1. Here is the beginning of a paragraph
|
---|
578 | ;" " that is very long...and this is a line
|
---|
579 | ;" " that has already wrapped.
|
---|
580 | ;" But the next line SHOULD NOT be pulled up if it is the start
|
---|
581 | ;" of a new paragraph. I will tell by looking for #. paattern.
|
---|
582 |
|
---|
583 |
|
---|
584 | ;"Result -- none
|
---|
585 |
|
---|
586 | if $get(TMGDEBUG)>0 do DebugEntry^TMGDEBUG(.DBIndent,"WordWrapArray^TMGSTUTL")
|
---|
587 | new tempArray set tempArray="" ;"holds result during work.
|
---|
588 | new tindex set tindex=0
|
---|
589 | new index
|
---|
590 | set index=$order(Array(""))
|
---|
591 | new s
|
---|
592 | new residualS set residualS=""
|
---|
593 | new AddZero set AddZero=0
|
---|
594 | set Width=$get(Width,70)
|
---|
595 |
|
---|
596 | if $get(TMGDEBUG)>0 do DebugMsg^TMGDEBUG(.DBIndent,"Starting loop")
|
---|
597 |
|
---|
598 | if index'="" for do quit:((index="")&(residualS=""))
|
---|
599 | . set s=$get(Array(index))
|
---|
600 | . if s="" do
|
---|
601 | . . set s=$get(Array(index,0))
|
---|
602 | . . set AddZero=1
|
---|
603 | . if residualS'="" do ;"See if should join to next line. Don't if '#. ' pattern
|
---|
604 | . . new FirstWord set FirstWord=$piece($$Trim(s)," ",1)
|
---|
605 | . . if $get(TMGDEBUG)>0 do DebugMsg^TMGDEBUG(.DBIndent,"First Word: ",FirstWord)
|
---|
606 | . . if (FirstWord?.N1".")!(FirstWord?1.4U1".") do ;"match for '#.' pattern
|
---|
607 | . . . ;"Here we have the next line is a new paragraph, so don't link to residualS
|
---|
608 | . . . set tindex=tindex+1
|
---|
609 | . . . if AddZero=0 set tempArray(tindex)=residualS
|
---|
610 | . . . else set tempArray(tindex,0)=residualS
|
---|
611 | . . . set residualS=""
|
---|
612 | . if $length(residualS)+$length(s)'<256 do
|
---|
613 | . . if $get(TMGDEBUG)>0 do DebugMsg^TMGDEBUG(.DBIndent,"ERROR -- string too long.")
|
---|
614 | . set s=residualS_s
|
---|
615 | . set residualS=""
|
---|
616 | . if $length(s)>Width do
|
---|
617 | . . if $get(TMGDEBUG)>0 do DebugMsg^TMGDEBUG(.DBIndent,"Long line: ",s)
|
---|
618 | . . new LineArray
|
---|
619 | . . new NumLines
|
---|
620 | . . set NumLines=$$SplitLine(.s,.LineArray,Width,.SpecialIndent)
|
---|
621 | . . if $get(TMGDEBUG)>0 do ArrayDump^TMGDEBUG("LineArray")
|
---|
622 | . . set s=""
|
---|
623 | . . new LineIndex
|
---|
624 | . . for LineIndex=1:1:NumLines do
|
---|
625 | . . . set tindex=tindex+1
|
---|
626 | . . . if AddZero=0 set tempArray(tindex)=LineArray(LineIndex)
|
---|
627 | . . . else set tempArray(tindex,0)=LineArray(LineIndex)
|
---|
628 | . . ;"long wrap probably continues into next paragraph, so link together.
|
---|
629 | . . if NumLines>2 do
|
---|
630 | . . . if AddZero=0 set residualS=tempArray(tindex) set tempArray(tindex)=""
|
---|
631 | . . . else set residualS=tempArray(tindex,0) set tempArray(tindex,0)=""
|
---|
632 | . . . set tindex=tindex-1
|
---|
633 | . else do
|
---|
634 | . . set tindex=tindex+1
|
---|
635 | . . if AddZero=0 set tempArray(tindex)=s
|
---|
636 | . . else set tempArray(tindex,0)=s
|
---|
637 | . set index=$order(Array(index))
|
---|
638 | else do
|
---|
639 | . if $get(TMGDEBUG)>0 do DebugMsg^TMGDEBUG(.DBIndent,"Array appears empty")
|
---|
640 |
|
---|
641 |
|
---|
642 | kill Array
|
---|
643 | merge Array=tempArray
|
---|
644 |
|
---|
645 | if $get(TMGDEBUG)>0 do ArrayDump^TMGDEBUG("Array")
|
---|
646 |
|
---|
647 | if $get(TMGDEBUG)>0 do DebugExit^TMGDEBUG(.DBIndent," WordWrapArray^TMGSTUTL")
|
---|
648 | quit
|
---|
649 |
|
---|
650 |
|
---|
651 | SplitLine(s,LineArray,Width,SpecialIndent,Indent)
|
---|
652 | ;"Scope: PUBLIC FUNCTION
|
---|
653 | ;"Purpose: To take a long line, and wrap into an array, such that each
|
---|
654 | ;" line is not longer than Width.
|
---|
655 | ;" Line breaks will be made at spaces, unless there are no spaces in
|
---|
656 | ;" the entire line (in which case, the line will be divided at Width).
|
---|
657 | ;"Input: s= string with the long line. **If passed by reference**, then
|
---|
658 | ;" it WILL BE CHANGED to equal the last line of array.
|
---|
659 | ;" LineArray -- MUST BE PASSED BY REFERENCE. This OUT variable will
|
---|
660 | ;" receive the resulting array.
|
---|
661 | ;" Width = the desired wrap width.
|
---|
662 | ;" SpecialIndent [OPTIONAL]: if 1, then wrapping is done like this:
|
---|
663 | ;" " This is a very long line......"
|
---|
664 | ;" will be wrapped like this:
|
---|
665 | ;" " This is a very
|
---|
666 | ;" " long line ...
|
---|
667 | ;" Notice that the leading space is copied subsequent line.
|
---|
668 | ;" Also, a line like this:
|
---|
669 | ;" " 1. Here is the beginning of a paragraph that is very long..."
|
---|
670 | ;" will be wrapped like this:
|
---|
671 | ;" " 1. Here is the beginning of a paragraph
|
---|
672 | ;" " that is very long..."
|
---|
673 | ;" Notice that a pattern '#. ' causes the wrapping to match the start
|
---|
674 | ;" of the text on the line above.
|
---|
675 | ;" Indent [OPTIONAL]: Any absolute amount that all lines should be indented by.
|
---|
676 | ;" This could be used if this long line is continuation of an
|
---|
677 | ;" indentation above it.
|
---|
678 | ;"Result: resulting number of lines (1 if no wrap needed).
|
---|
679 |
|
---|
680 | if $get(TMGDEBUG)>0 do DebugEntry^TMGDEBUG(.DBIndent,"SplitLine")
|
---|
681 |
|
---|
682 | new result set result=0
|
---|
683 | kill LineArray
|
---|
684 | if ($get(s)="")!($get(Width)'>0) goto SPDone
|
---|
685 | new index set index=0
|
---|
686 | new p,tempS,splitPoint
|
---|
687 |
|
---|
688 | new PreSpace set PreSpace=$$NeededWS(s,.SpecialIndent,.Indent)
|
---|
689 |
|
---|
690 | if ($length(s)>Width) for do quit:($length(s)'>Width)
|
---|
691 | . for splitPoint=1:1:Width do quit:($length(tempS)>Width)
|
---|
692 | . . set tempS=$piece(s," ",1,splitPoint)
|
---|
693 | . . ;"write "tempS>",tempS,!
|
---|
694 | . if splitPoint>1 do
|
---|
695 | . . set tempS=$piece(s," ",1,splitPoint-1)
|
---|
696 | . . set s=$piece(s," ",splitPoint,Width)
|
---|
697 | . else do
|
---|
698 | . . ;"We must have a word > Width with no spaces--so just divide
|
---|
699 | . . set tempS=$extract(s,1,Width)
|
---|
700 | . . set s=$extract(s,Width+1,999)
|
---|
701 | . set index=index+1
|
---|
702 | . set LineArray(index)=tempS
|
---|
703 | . set s=PreSpace_s
|
---|
704 | . ;"write "tempS>",tempS,!
|
---|
705 | . ;"write "s>",s,!
|
---|
706 |
|
---|
707 | set index=index+1
|
---|
708 | set LineArray(index)=s
|
---|
709 |
|
---|
710 | set result=index
|
---|
711 |
|
---|
712 | SPDone
|
---|
713 | if $get(TMGDEBUG)>0 do DebugExit^TMGDEBUG(.DBIndent,"SplitLine")
|
---|
714 | quit result
|
---|
715 |
|
---|
716 |
|
---|
717 |
|
---|
718 | NeededWS(S,SpecialIndent,Indent)
|
---|
719 | ;"Scope: PRIVATE
|
---|
720 | ;"Purpose: Evaluate the line, and create the white space string
|
---|
721 | ;" need for wrapped lines
|
---|
722 | ;"Input: s -- the string to eval. i.e.
|
---|
723 | ;" " John is very happy today ... .. .. .. .."
|
---|
724 | ;" or " 1. John is very happy today ... .. .. .. .."
|
---|
725 | ;" SpecialIndent -- See SplitLine() discussion
|
---|
726 | ;" Indent -- See SplitLine() discussion
|
---|
727 |
|
---|
728 | new result set result=""
|
---|
729 | if $get(S)="" goto NdWSDone
|
---|
730 |
|
---|
731 | new WSNum
|
---|
732 | set WSNum=+$get(Indent,0)
|
---|
733 | set WSNum=WSNum+$$NumLWS(S)
|
---|
734 |
|
---|
735 | if $get(SpecialIndent)=1 do
|
---|
736 | . new ts,FirstWord
|
---|
737 | . set ts=$$TrimL(.S)
|
---|
738 | . set FirstWord=$piece(ts," ",1)
|
---|
739 | . if (FirstWord?.N1".")!(FirstWord?1.4U1".") do ;"match for '#.' pattern
|
---|
740 | . . set WSNum=WSNum+$length(FirstWord)
|
---|
741 | . . set ts=$piece(ts," ",2,9999)
|
---|
742 | . . set WSNum=WSNum+$$NumLWS(.ts)+1
|
---|
743 |
|
---|
744 | set result=$$MakeWS(WSNum)
|
---|
745 |
|
---|
746 | NdWSDone
|
---|
747 | quit result
|
---|
748 |
|
---|
749 |
|
---|
750 | WriteWP(NodeRef)
|
---|
751 | ;"Purpose: Given a reference to a WP field, this function will print it out.
|
---|
752 | ;"INput: NodeRef -- the name of the node to print out.
|
---|
753 | ;" For example, "^PS(50.605,1,1)"
|
---|
754 | ;"Modification: 2/10/06 -- I removed need for @NodeRef@(0) to contain data.
|
---|
755 |
|
---|
756 | new i
|
---|
757 | ;"if $get(@NodeRef@(0))="" goto WWPDone
|
---|
758 | set i=$order(@NodeRef@(0))
|
---|
759 | if i'="" for do quit:(i="")
|
---|
760 | . new OneLine
|
---|
761 | . set OneLine=$get(@NodeRef@(i))
|
---|
762 | . if OneLine="" set OneLine=$get(@NodeRef@(i,0))
|
---|
763 | . write OneLine,!
|
---|
764 | . set i=$order(@NodeRef@(i))
|
---|
765 |
|
---|
766 | WWPDone quit
|
---|
767 |
|
---|
768 |
|
---|
769 | LPad(S,width)
|
---|
770 | ;"Purpose: To add space ("pad") string S such that final width is per specified with.
|
---|
771 | ;" space is added to left side of string
|
---|
772 | ;"Input: S : the string to pad.
|
---|
773 | ;" width : the desired final width
|
---|
774 | ;"result: returns resulting string
|
---|
775 | ;"Example: LPad("$5.23",7)=" $5.23"
|
---|
776 |
|
---|
777 | quit $$RJ^XLFSTR(.S,.width," ")
|
---|
778 |
|
---|
779 | RPad(S,width)
|
---|
780 | ;"Purpose: To add space ("pad") string S such that final width is per specified with.
|
---|
781 | ;" space is added to right side of string
|
---|
782 | ;"Input: S : the string to pad.
|
---|
783 | ;" width : the desired final width
|
---|
784 | ;"result: returns resulting string
|
---|
785 | ;"Example: RPad("$5.23",7)="$5.23 "
|
---|
786 |
|
---|
787 | quit $$LJ^XLFSTR(.S,.width," ")
|
---|
788 |
|
---|
789 | Center(S,width)
|
---|
790 | ;"Purpose: to return a center justified string
|
---|
791 |
|
---|
792 | quit $$CJ^XLFSTR(.S,.width," ")
|
---|
793 |
|
---|
794 | Clip(S,width)
|
---|
795 | ;"Purpose: to ensure that string S is no longer than width
|
---|
796 |
|
---|
797 | new result set result=$get(S)
|
---|
798 | if result'="" set result=$extract(S,1,width)
|
---|
799 | ClipDone
|
---|
800 | quit result
|
---|
801 |
|
---|
802 |
|
---|
803 | STRB2H(s,F,noSpace)
|
---|
804 | ;"Convert a string to hex characters)
|
---|
805 | ;"Input: s -- the input string (need not be ascii characters)
|
---|
806 | ;" F -- (optional) if F>0 then will append an ascii display of string.
|
---|
807 | ;" noSpace -- (Optional) if >0 then characters NOT separated by spaces
|
---|
808 | ;"result -- the converted string
|
---|
809 |
|
---|
810 | new i,ch
|
---|
811 | new result set result=""
|
---|
812 |
|
---|
813 | for i=1:1:$length(s) do
|
---|
814 | . set ch=$extract(s,i)
|
---|
815 | . set result=result_$$HEXCHR^TMGMISC($ascii(ch))
|
---|
816 | . if +$get(noSpace)=0 set result=result_" "
|
---|
817 |
|
---|
818 | if $get(F)>0 set result=result_" "_$$HIDECTRLS^TMGSTUTL(s)
|
---|
819 | quit result
|
---|
820 |
|
---|
821 |
|
---|
822 | HIDECTRLS(s)
|
---|
823 | ;"hide all unprintable characters from a string
|
---|
824 | new i,ch,byte
|
---|
825 | new result set result=""
|
---|
826 | for i=1:1:$length(s) do
|
---|
827 | . set ch=$e(s,i)
|
---|
828 | . set byte=$ascii(ch)
|
---|
829 | . if (byte<32)!(byte>122) set result=result_"."
|
---|
830 | . else set result=result_ch
|
---|
831 |
|
---|
832 | quit result
|
---|
833 |
|
---|
834 |
|
---|
835 |
|
---|
836 | CapWords(S,Divider)
|
---|
837 | ;"Purpose: convert each word in the string: 'test string' --> 'Test String', 'TEST STRING' --> 'Test String'
|
---|
838 |
|
---|
839 | ;"Input: S -- the string to convert
|
---|
840 | ;" Divider -- [OPTIONAL] the character used to separate string (default is ' ' [space])
|
---|
841 | ;"Result: returns the converted string
|
---|
842 |
|
---|
843 | new s2,part
|
---|
844 | new result set result=""
|
---|
845 | set Divider=$get(Divider," ")
|
---|
846 |
|
---|
847 | set s2=$$LOW^XLFSTR(S)
|
---|
848 |
|
---|
849 | for i=1:1 do quit:part=""
|
---|
850 | . set part=$piece(s2,Divider,i)
|
---|
851 | . if part="" quit
|
---|
852 | . set $extract(part,1)=$$UP^XLFSTR($extract(part,1))
|
---|
853 | . if result'="" set result=result_Divider
|
---|
854 | . set result=result_part
|
---|
855 |
|
---|
856 | quit result
|
---|
857 |
|
---|
858 |
|
---|
859 | LinuxStr(S)
|
---|
860 | ;"Purpose: convert string to a valid linux filename
|
---|
861 | ;" e.g. 'File Name' --> 'File\ Name'
|
---|
862 |
|
---|
863 | quit $$Substitute(.S," ","\ ")
|
---|
864 |
|
---|
865 |
|
---|
866 |
|
---|
867 | NiceSplit(S,Len,s1,s2,s2Min,DivCh)
|
---|
868 | ;"Purpose: to split S into two strings, s1 & s2
|
---|
869 | ;" Furthermore, s1's length must be <= length.
|
---|
870 | ;" and the split will be made at spaces
|
---|
871 | ;"Input: S -- the string to split
|
---|
872 | ;" Len -- the length limit of s1
|
---|
873 | ;" s1 -- PASS BY REFERENCE, an OUT parameter
|
---|
874 | ;" receives first part of split
|
---|
875 | ;" s2 -- PASS BY REFERENCE, an OUT parameter
|
---|
876 | ;" receives the rest of string
|
---|
877 | ;" s2Min -- OPTIONAL -- the minimum that
|
---|
878 | ;" length of s2 can be. Note, if s2
|
---|
879 | ;" is "", then this is not applied
|
---|
880 | ;" DivCH -- OPTIONAL, default is " ".
|
---|
881 | ;" This is the character to split words by
|
---|
882 | ;"Output: s1 and s2 is filled with data
|
---|
883 | ;"Result: none
|
---|
884 |
|
---|
885 | set (s1,s2)=""
|
---|
886 | if $get(DivCh)="" set DivCh=" "
|
---|
887 |
|
---|
888 | if $length(S)'>Len do goto NSpDone
|
---|
889 | . set s1=S
|
---|
890 |
|
---|
891 | new i
|
---|
892 | new done
|
---|
893 | for i=200:-1:1 do quit:(done)
|
---|
894 | . set s1=$piece(S,DivCh,1,i)_DivCh
|
---|
895 | . set s2=$piece(S,DivCh,i+1,999)
|
---|
896 | . set done=($length(s1)'>Len)
|
---|
897 | . if done,+$get(s2Min)>0 do
|
---|
898 | . . if s2="" quit
|
---|
899 | . . set done=($length(s2)'<s2Min)
|
---|
900 |
|
---|
901 | NSpDone quit
|
---|
902 |
|
---|
903 |
|
---|
904 | StrToWP(s,pArray,width,DivCh,InitLine)
|
---|
905 | ;"Purpose: to take a long string and wrap it into formal WP format
|
---|
906 | ;"Input: s: the long string to wrap into the WP field
|
---|
907 | ;" pArray: the NAME of the array to put output into.
|
---|
908 | ;" Any pre-existing data in this array will NOT be killed
|
---|
909 | ;" width: OPTIONAL -- the width to target for word wrapping. Default is 60
|
---|
910 | ;" DivCh: OPTIONAL -- the character to use separate words (to allow nice wrapping). Default is " "
|
---|
911 | ;" InitLine: OPTIONAL -- the line to start putting data into. Default is 1
|
---|
912 | ;"Output: pArray will be filled as follows:
|
---|
913 | ;" @pArray@(InitLine+0)=line 1
|
---|
914 | ;" @pArray@(InitLine+1)=line 2
|
---|
915 | ;" @pArray@(InitLine+2)=line 3
|
---|
916 |
|
---|
917 | if +$get(width)=0 set width=60
|
---|
918 | if $get(DivCh)="" set DivCh=" "
|
---|
919 | new tempS set tempS=$get(s)
|
---|
920 | if $get(InitLine)="" set InitLine=1
|
---|
921 | new curLine set curLine=+InitLine
|
---|
922 | ;"kill @pArray
|
---|
923 |
|
---|
924 | for do quit:(tempS="")
|
---|
925 | . new s1,s2
|
---|
926 | . do NiceSplit(tempS,width,.s1,.s2,,DivCh)
|
---|
927 | . set @pArray@(curLine)=s1
|
---|
928 | . set curLine=curLine+1
|
---|
929 | . set tempS=s2
|
---|
930 |
|
---|
931 | quit
|
---|
932 |
|
---|
933 |
|
---|
934 | WPToStr(pArray,DivCh,MaxLen,InitLine)
|
---|
935 | ;"Purpose: This is the opposite of StrToWP. It takes a WP field, and concatenates
|
---|
936 | ;" each line to make one long string.
|
---|
937 | ;"Input: pArray: the NAME of the array to get WP lines from. Expected format as follows
|
---|
938 | ;" @pArray@(InitLine+0)=line 1
|
---|
939 | ;" @pArray@(InitLine+1)=line 2
|
---|
940 | ;" @pArray@(InitLine+2)=line 3
|
---|
941 | ;" -or-
|
---|
942 | ;" @pArray@(InitLine+0,0)=line 1
|
---|
943 | ;" @pArray@(InitLine+1,0)=line 2
|
---|
944 | ;" @pArray@(InitLine+2,0)=line 3
|
---|
945 | ;" DivCh: OPTIONAL, default is " ". This character is appended to the end of each line, e.g
|
---|
946 | ;" output=output_line1_DivCh_line2
|
---|
947 | ;" MaxLen: OPTIONAL, default=255. The maximum allowable length of the resulting string.
|
---|
948 | ;" InitLine: OPTIONAL -- the line in pArray to start reading data from. Default is 1
|
---|
949 | ;"result: Returns one long string representing the WP array
|
---|
950 |
|
---|
951 | new i,OneLine,result,Len
|
---|
952 | set i=$get(InitLine,1)
|
---|
953 | set result=""
|
---|
954 | set DivCh=$get(DivCh," ")
|
---|
955 | set MaxLen=$get(MaxLen,255)
|
---|
956 | set Len=0
|
---|
957 |
|
---|
958 | for do quit:(OneLine="")!(Len'<MaxLen)!(+i'>0)
|
---|
959 | . set OneLine=$get(@pArray@(i))
|
---|
960 | . if OneLine="" set OneLine=$get(@pArray@(i,0))
|
---|
961 | . if OneLine="" quit
|
---|
962 | . set Len=$length(result)+$length(DivCh)
|
---|
963 | . if Len+$length(OneLine)>MaxLen do
|
---|
964 | . . set OneLine=$extract(OneLine,1,(MaxLen-Len))
|
---|
965 | . set result=result_OneLine_DivCh
|
---|
966 | . set Len=Len+$length(OneLine)
|
---|
967 | . set i=$order(@pArray@(i))
|
---|
968 |
|
---|
969 | quit result;
|
---|
970 |
|
---|
971 |
|
---|
972 | Comp2Strs(s1,s2)
|
---|
973 | ;"Purpose: To compare two strings and assign an arbritrary score to their similarity
|
---|
974 | ;"Input: s1,s2 -- The two strings to compare
|
---|
975 | ;"Result: a score comparing the two strings
|
---|
976 | ;" 0.5 point for every word in s1 that is also in s2 (case specific)
|
---|
977 | ;" 0.25 point for every word in s1 that is also in s2 (not case specific)
|
---|
978 | ;" 0.5 point for every word in s2 that is also in s1 (case specific)
|
---|
979 | ;" 0.25 point for every word in s2 that is also in s1 (not case specific)
|
---|
980 | ;" 1 points if same number of words in string (compared each way)
|
---|
981 | ;" 2 points for each word that is in the same position in each string (case specific)
|
---|
982 | ;" 1.5 points for each word that is in the same position in each string (not case specific)
|
---|
983 |
|
---|
984 | new score set score=0
|
---|
985 | new Us1 set Us1=$$UP^XLFSTR(s1)
|
---|
986 | new Us2 set Us2=$$UP^XLFSTR(s2)
|
---|
987 |
|
---|
988 | new i
|
---|
989 | for i=1:1:$length(s1," ") do
|
---|
990 | . if s2[$piece(s1," ",i) set score=score+0.5
|
---|
991 | . else if Us2[$piece(Us1," ",i) set score=score+0.25
|
---|
992 | . if $piece(s1," ",i)=$piece(s2," ",i) set score=score+1
|
---|
993 | . else if $piece(Us1," ",i)=$piece(Us2," ",i) set score=score+1.5
|
---|
994 |
|
---|
995 | for i=1:1:$length(s2," ") do
|
---|
996 | . if s1[$piece(s2," ",i) set score=score+0.5
|
---|
997 | . else if Us1[$piece(Us2," ",i) set score=score+0.25
|
---|
998 | . if $piece(s1," ",i)=$piece(s2," ",i) set score=score+1
|
---|
999 | . else if $piece(Us1," ",i)=$piece(Us2," ",i) set score=score+1.5
|
---|
1000 |
|
---|
1001 | if $length(s1," ")=$length(s2," ") set score=score+2
|
---|
1002 |
|
---|
1003 | quit score
|
---|
1004 |
|
---|
1005 |
|
---|
1006 | PosNum(s,Num,LeadingSpace)
|
---|
1007 | ;"Purpose: To return the position of the first Number in a string
|
---|
1008 | ;"Input: S -- string to check
|
---|
1009 | ;" Num -- OPTIONAL, default is 0-9 numbers. number to look for.
|
---|
1010 | ;" LeadingSpace -- OPTIONAL. If 1 then looks for " #" or " .#", not just "#"
|
---|
1011 | ;"Results: -1 if not found, otherwise position of found digit.
|
---|
1012 |
|
---|
1013 | new result set result=-1
|
---|
1014 | new Leader set Leader=""
|
---|
1015 | if $get(LeadingSpace)=1 set Leader=" "
|
---|
1016 |
|
---|
1017 | if $get(Num) do goto PNDone
|
---|
1018 | . set result=$find(s,Leader_Num)-1
|
---|
1019 |
|
---|
1020 | new temp,i,decimalFound
|
---|
1021 | for i=0:1:9 do
|
---|
1022 | . set decimalFound=0
|
---|
1023 | . set temp=$find(s,Leader_i)
|
---|
1024 | . if (temp=0)&(Leader'="") do
|
---|
1025 | . . set temp=$find(s,Leader_"."_i)
|
---|
1026 | . . if temp>-1 set decimalFound=1
|
---|
1027 | . if temp>-1 set temp=temp-$length(Leader_i)
|
---|
1028 | . if decimalFound set temp=temp-1
|
---|
1029 | . if (temp>0)&((temp<result)!(result=-1)) set result=temp
|
---|
1030 |
|
---|
1031 | PNDone
|
---|
1032 | if (result>0)&(Leader=" ") set result=result+1
|
---|
1033 | quit result
|
---|
1034 |
|
---|
1035 |
|
---|
1036 | IsNumeric(s)
|
---|
1037 | ;"Purpose: To deterimine if word s is a numeric
|
---|
1038 | ;" Examples of numeric words:
|
---|
1039 | ;" 10, N-100, 0.5%, 50000UNT/ML
|
---|
1040 | ;" the test will be if the word contains any digit 0-9
|
---|
1041 | ;"Results: 1 if is a numeric word, 0 if not.
|
---|
1042 |
|
---|
1043 | quit ($$PosNum(.s)>0)
|
---|
1044 |
|
---|
1045 |
|
---|
1046 | ScrubNumeric(s)
|
---|
1047 | ;"Purpose: This is a specialty function designed to remove numeric words
|
---|
1048 | ;" from a sentence. E.g.
|
---|
1049 | ;" BELLADONNA ALK 0.3/PHENOBARB 16MG CHW TB --> BELLADONNA ALK /PHENOBARB CHW TB
|
---|
1050 | ;" ESTROGENS,CONJUGATED 2MG/ML INJ (IN OIL) --> ESTROGENS,CONJUGATED INJ (IN OIL)
|
---|
1051 |
|
---|
1052 | new Array,i,result
|
---|
1053 | set s=$$Substitute(s,"/MG","")
|
---|
1054 | set s=$$Substitute(s,"/ML","")
|
---|
1055 | set s=$$Substitute(s,"/"," / ")
|
---|
1056 | set s=$$Substitute(s,"-"," - ")
|
---|
1057 | do CleaveToArray(s," ",.Array)
|
---|
1058 | new ToKill
|
---|
1059 | set i=0 for set i=$order(Array(i)) quit:+i'>0 do
|
---|
1060 | . if (Array(i)="MG")&($get(ToKill(i-1))=1) set ToKill(i)=1 quit
|
---|
1061 | . if (Array(i)="MCG")&($get(ToKill(i-1))=1) set ToKill(i)=1 quit
|
---|
1062 | . if (Array(i)="MEQ")&($get(ToKill(i-1))=1) set ToKill(i)=1 quit
|
---|
1063 | . if (Array(i)="%")&($get(ToKill(i-1))=1) set ToKill(i)=1 quit
|
---|
1064 | . if (Array(i)="MM")&($get(ToKill(i-1))=1) set ToKill(i)=1 quit
|
---|
1065 | . if $$IsNumeric(Array(i))=0 quit
|
---|
1066 | . set ToKill(i)=1
|
---|
1067 | . new tempS set tempS=$get(Array(i-1))
|
---|
1068 | . if (tempS="/")!(tempS="-") set ToKill(i-1)=1
|
---|
1069 | . if (tempS="NO")!(tempS="#") set ToKill(i-1)=1
|
---|
1070 |
|
---|
1071 | set i=0 for set i=$order(Array(i)) quit:+i'>0 do
|
---|
1072 | . if $get(ToKill(i))=1 kill Array(i)
|
---|
1073 |
|
---|
1074 | set i="",result=""
|
---|
1075 | for set i=$order(Array(i)) quit:+i'>0 do
|
---|
1076 | . set result=result_Array(i)_" "
|
---|
1077 |
|
---|
1078 | set result=$$Trim(result)
|
---|
1079 | set result=$$Substitute(result," / ","/")
|
---|
1080 | set result=$$Substitute(result," - ","-")
|
---|
1081 |
|
---|
1082 | quit result
|
---|
1083 |
|
---|
1084 |
|
---|
1085 | Pos(subStr,s,count)
|
---|
1086 | ;"Purpose: return the beginning position of subStr in s
|
---|
1087 | ;"Input: subStr -- the string to be searched for in s
|
---|
1088 | ;" s -- the string to search
|
---|
1089 | ;" count -- OPTIONAL, the instance to return pos of (1=1st, 2=2nd, etc.)
|
---|
1090 | ;" if count=2 and only 1 instance exists, then 0 returned
|
---|
1091 | ;"Result: the beginning position, or 0 if not found
|
---|
1092 | ;"Note: This function differs from $find in that $find returns the pos of the
|
---|
1093 | ;" first character AFTER the subStr
|
---|
1094 |
|
---|
1095 | set count=$get(count,1)
|
---|
1096 | new result set result=0
|
---|
1097 | new instance set instance=1
|
---|
1098 | PS1
|
---|
1099 | set result=$find(s,subStr,result+1)
|
---|
1100 | if result>0 set result=result-$length(subStr)
|
---|
1101 | if count>instance set instance=instance+1 goto PS1
|
---|
1102 |
|
---|
1103 | quit result
|
---|
1104 |
|
---|
1105 |
|
---|
1106 | ArrayPos(array,s)
|
---|
1107 | ;"Purpose: return the index position of s in array
|
---|
1108 |
|
---|
1109 | ;"...
|
---|
1110 |
|
---|
1111 | quit
|
---|
1112 |
|
---|
1113 | DiffPos(s1,s2)
|
---|
1114 | ;"Purpose: Return the position of the first difference between s1 and s2
|
---|
1115 | ;"Input -- s1, s2 : The strings to compare.
|
---|
1116 | ;"result: the position (in s1) of the first difference, or 0 if no difference
|
---|
1117 |
|
---|
1118 | new l set l=$length(s1)
|
---|
1119 | if $length(s2)>l set l=$length(s2)
|
---|
1120 | new done set done=0
|
---|
1121 | new i for i=1:1:l do quit:(done=1)
|
---|
1122 | . set done=($extract(s1,1,i)'=$extract(s2,1,i))
|
---|
1123 | new result set result=0
|
---|
1124 | if done=1 set result=i
|
---|
1125 | quit result
|
---|
1126 |
|
---|
1127 |
|
---|
1128 | DiffWPos(Words1,Words2)
|
---|
1129 | ;"Purpose: Return the index of the first different word between Words arrays
|
---|
1130 | ;"Input: Words1,Words2 -- the array of words, such as would be made
|
---|
1131 | ;" by CleaveToArray^TMGSTUTL
|
---|
1132 | ;"Returns: Index of first different word in Words1, or 0 if no difference
|
---|
1133 |
|
---|
1134 | new l set l=+$get(Words1("MAXNODE"))
|
---|
1135 | if +$get(Words2("MAXNODE"))>l set l=+$get(Words2("MAXNODE"))
|
---|
1136 | new done set done=0
|
---|
1137 | new i for i=1:1:l do quit:(done=1)
|
---|
1138 | . set done=($get(Words1(i))'=$get(Words2(i)))
|
---|
1139 | new result
|
---|
1140 | if done=1 set result=i
|
---|
1141 | else set result=0
|
---|
1142 | quit result
|
---|
1143 |
|
---|
1144 |
|
---|
1145 | SimStr(s1,p1,s2,p2)
|
---|
1146 | ;"Purpose: return the matching string in both s1 and s2, starting
|
---|
1147 | ;" at positions p1 and p2.
|
---|
1148 | ;" Example: s1='Tom is 12 years old', p1=7
|
---|
1149 | ;" s2='Bill will be 12 years young tomorrow' p2=13
|
---|
1150 | ;" would return ' 12 years '
|
---|
1151 |
|
---|
1152 | new ch1,ch2,offset,result,done
|
---|
1153 | set result="",done=0
|
---|
1154 | for offset=0:1:9999 do quit:(done=1)
|
---|
1155 | . set ch1=$extract(s1,p1+offset)
|
---|
1156 | . set ch2=$extract(s2,p2+offset)
|
---|
1157 | . if (ch1=ch2) set result=result_ch1
|
---|
1158 | . else set done=1
|
---|
1159 | quit result
|
---|
1160 |
|
---|
1161 |
|
---|
1162 | SimWord(Words1,p1,Words2,p2)
|
---|
1163 | ;"Purpose: return the matching words in both words array 1 and 2, starting
|
---|
1164 | ;" at word positions p1 and p2. This function is different from
|
---|
1165 | ;" SimStr in that it works with whole words
|
---|
1166 | ;" Example:
|
---|
1167 | ;" Words1(1)=Tom Words2(1)=Bill
|
---|
1168 | ;" Words1(2)=is Words2(2)=will
|
---|
1169 | ;" Words1(3)=12 Words2(3)=be
|
---|
1170 | ;" Words1(4)=years Words2(4)=12
|
---|
1171 | ;" Words1(5)=old Words2(5)=years
|
---|
1172 | ;" Words1("MAXNODE")=5 Words2(6)=young
|
---|
1173 | ;" Words2(7)=tomorrow
|
---|
1174 | ;" Words1("MAXNODE")=7
|
---|
1175 | ;" This will return 3, (where '12 years' starts)
|
---|
1176 | ;" if p1=3 and p2=4 would return '12 years'
|
---|
1177 | ;"Note: A '|' will be used as word separator when constructing result
|
---|
1178 | ;"Input: Words1,Words2 -- the array of words, such as would be made
|
---|
1179 | ;" by CleaveToArray^TMGSTUTL. e.g.
|
---|
1180 | ;" p1,p2 -- the index of the word in Words array to start with
|
---|
1181 | ;"result: (see example)
|
---|
1182 |
|
---|
1183 | new w1,w2,offset,result,done
|
---|
1184 | set result="",done=0
|
---|
1185 | for offset=0:1:$get(Words1("MAXNODE")) do quit:(done=1)
|
---|
1186 | . set w1=$get(Words1(offset+p1))
|
---|
1187 | . set w2=$get(Words2(offset+p2))
|
---|
1188 | . if (w1=w2)&(w1'="") do
|
---|
1189 | . . if (result'="") set result=result_"|"
|
---|
1190 | . . set result=result_w1
|
---|
1191 | . else set done=1
|
---|
1192 | quit result
|
---|
1193 |
|
---|
1194 |
|
---|
1195 | SimPos(s1,s2,DivStr,pos1,pos2,MatchStr)
|
---|
1196 | ;"Purpose: return the first position that two strings are similar. This means
|
---|
1197 | ;" the first position in string s1 that characters match in s2. A
|
---|
1198 | ;" match will be set to mean 3 or more characters being the same.
|
---|
1199 | ;" Example: s1='Tom is 12 years old'
|
---|
1200 | ;" s2='Bill will be 12 years young tomorrow'
|
---|
1201 | ;" This will return 7, (where '12 years' starts)
|
---|
1202 | ;"Input: s1,s2 -- the two strings to compare
|
---|
1203 | ;" DivStr -- OPTIONAL, the character to use to separate the answers
|
---|
1204 | ;" in the return string. Default is '^'
|
---|
1205 | ;" pos1 -- OPTIONAL, an OUT PARAMETER. Returns Pos1 from result
|
---|
1206 | ;" pos2 -- OPTIONAL, an OUT PARAMETER. Returns Pos2 from result
|
---|
1207 | ;" MatchStr -- OPTIONAL, an OUT PARAMETER. Returns MatchStr from result
|
---|
1208 | ;"Results: Pos1^Pos2^MatchStr Pos1=position in s1, Pos2=position in s2,
|
---|
1209 | ;" MatchStr=the matching Str
|
---|
1210 |
|
---|
1211 | set DivStr=$get(DivStr,"^")
|
---|
1212 | new startPos,subStr,found,s2Pos
|
---|
1213 | set found=0,s2Pos=0
|
---|
1214 | for startPos=1:1:$length(s1) do quit:(found=1)
|
---|
1215 | . set subStr=$extract(s1,startPos,startPos+3)
|
---|
1216 | . set s2Pos=$$Pos(subStr,s2)
|
---|
1217 | . set found=(s2Pos>0)
|
---|
1218 |
|
---|
1219 | new result
|
---|
1220 | if found=1 do
|
---|
1221 | . set pos1=startPos,pos2=s2Pos
|
---|
1222 | . set MatchStr=$$SimStr(s1,startPos,s2,s2Pos)
|
---|
1223 | else do
|
---|
1224 | . set pos1=0,pos2=0,MatchStr=""
|
---|
1225 |
|
---|
1226 | set result=pos1_DivStr_pos2_DivStr_MatchStr
|
---|
1227 |
|
---|
1228 | quit result
|
---|
1229 |
|
---|
1230 |
|
---|
1231 | SimWPos(Words1,Words2,DivStr,p1,p2,MatchStr)
|
---|
1232 | ;"Purpose: return the first position that two word arrays are similar. This means
|
---|
1233 | ;" the first index in Words array 1 that matches to words in Words array 2.
|
---|
1234 | ;" A match will be set to mean the two words are equal
|
---|
1235 | ;" Example:
|
---|
1236 | ;" Words1(1)=Tom Words2(1)=Bill
|
---|
1237 | ;" Words1(2)=is Words2(2)=will
|
---|
1238 | ;" Words1(3)=12 Words2(3)=be
|
---|
1239 | ;" Words1(4)=years Words2(4)=12
|
---|
1240 | ;" Words1(5)=old Words2(5)=years
|
---|
1241 | ;" Words1("MAXNODE")=5 Words2(6)=young
|
---|
1242 | ;" Words2(7)=tomorrow
|
---|
1243 | ;" Words2("MAXNODE")=7
|
---|
1244 | ;" This will return 3, (where '12 years' starts)
|
---|
1245 | ;"Input: Words1,Words2 -- the two arrays to compare
|
---|
1246 | ;" DivStr -- OPTIONAL, the character to use to separate the answers
|
---|
1247 | ;" in the return string. Default is '^'
|
---|
1248 | ;" pos1 -- OPTIONAL, an OUT PARAMETER. Returns Pos1 from result
|
---|
1249 | ;" pos2 -- OPTIONAL, an OUT PARAMETER. Returns Pos2 from result
|
---|
1250 | ;" MatchStr -- OPTIONAL, an OUT PARAMETER. Returns MatchStr from result
|
---|
1251 | ;"Results: Pos1^Pos2^MatchStr Pos1=position in Words1, Pos2=position in Words2,
|
---|
1252 | ;" MatchStr=the first matching Word or phrase
|
---|
1253 | ;" Note: | will be used as a word separator for phrases.
|
---|
1254 |
|
---|
1255 | set DivStr=$get(DivStr,"^")
|
---|
1256 | new startPos,word1,found,w2Pos
|
---|
1257 | set found=0,s2Pos=0
|
---|
1258 | for startPos=1:1:+$get(Words1("MAXNODE")) do quit:(found=1)
|
---|
1259 | . set word1=$get(Words1(startPos))
|
---|
1260 | . set w2Pos=$$IndexOf^TMGMISC($name(Words2),word1)
|
---|
1261 | . set found=(w2Pos>0)
|
---|
1262 |
|
---|
1263 | if found=1 do
|
---|
1264 | . set p1=startPos,p2=w2Pos
|
---|
1265 | . set MatchStr=$$SimWord(.Words1,p1,.Words2,p2)
|
---|
1266 | else do
|
---|
1267 | . set p1=0,p2=0,MatchStr=""
|
---|
1268 |
|
---|
1269 | new result set result=p1_DivStr_p2_DivStr_MatchStr
|
---|
1270 |
|
---|
1271 | quit result
|
---|
1272 |
|
---|
1273 |
|
---|
1274 | DiffStr(s1,s2,DivChr)
|
---|
1275 | ;"Purpose: Return how s1 differs from s2. E.g.
|
---|
1276 | ;" s1='Today was the birthday of Bill and John'
|
---|
1277 | ;" s2='Yesterday was the birthday of Tom and Sue'
|
---|
1278 | ;" results='Today^1^Bill^26^John^35'
|
---|
1279 | ;" This means that 'Today', starting at pos 1 in s1 differs
|
---|
1280 | ;" from s2. And 'Bill' starting at pos 26 differs from s2 etc..
|
---|
1281 | ;"Input: s1,s2 -- the two strings to compare
|
---|
1282 | ;" DivStr -- OPTIONAL, the character to use to separate the answers
|
---|
1283 | ;" in the return string. Default is '^'
|
---|
1284 | ;"Results: DiffStr1^pos1^DiffStr2^pos2^...
|
---|
1285 |
|
---|
1286 | set DivChr=$get(DivChr,"^")
|
---|
1287 | new result set result=""
|
---|
1288 | new offset set offset=0
|
---|
1289 | new p1,p2,matchStr,matchLen
|
---|
1290 | new diffStr,temp
|
---|
1291 | DSLoop
|
---|
1292 | set temp=$$SimPos(s1,s2,DivChr,.p1,.p2,.matchStr)
|
---|
1293 | ;"Returns: Pos1^Pos2^MatchStr Pos1=pos in s1, Pos2=pos in s2, MatchStr=the matching Str
|
---|
1294 | if p1=0 set:(s1'="") result=result_s1_DivChr_(+offset) goto DSDone
|
---|
1295 |
|
---|
1296 | set matchLen=$length(matchStr)
|
---|
1297 |
|
---|
1298 | if p1>1 do
|
---|
1299 | . set diffStr=$extract(s1,1,p1-1)
|
---|
1300 | . set result=result_diffStr_DivChr_(1+offset)_DivChr
|
---|
1301 | set offset=offset+(p1+matchLen-1)
|
---|
1302 | set s1=$extract(s1,p1+matchLen,9999) ;"trim s1
|
---|
1303 | set s2=$extract(s2,p2+matchLen,9999) ;"trim s2
|
---|
1304 | goto DSLoop
|
---|
1305 | DSDone
|
---|
1306 | quit result
|
---|
1307 |
|
---|
1308 |
|
---|
1309 | DiffWords(Words1,Words2,DivChr)
|
---|
1310 | ;"Purpose: Return how Word arrays Words1 differs from Words2. E.g.
|
---|
1311 | ;" Example:
|
---|
1312 | ;" Words1(1)=Tom Words2(1)=Bill
|
---|
1313 | ;" Words1(2)=is Words2(2)=will
|
---|
1314 | ;" Words1(3)=12 Words2(3)=be
|
---|
1315 | ;" Words1(4)=years Words2(4)=12
|
---|
1316 | ;" Words1(5)=old Words2(5)=years
|
---|
1317 | ;" Words1("MAXNODE")=5 Words2(6)=young
|
---|
1318 | ;" Words2(7)=tomorrow
|
---|
1319 | ;" Words1("MAXNODE")=7
|
---|
1320 | ;"
|
---|
1321 | ;" s1='Today was the birthday of Bill and John'
|
---|
1322 | ;" s2='Yesterday was the birthday of Tom and Sue'
|
---|
1323 | ;" results='Tom is^1^old^5'
|
---|
1324 | ;" This means that 'Tom is', starting at pos 1 in Words1 differs
|
---|
1325 | ;" from Words2. And 'old' starting at pos 5 differs from Words2 etc..
|
---|
1326 | ;"Input: Words1,Words2 -- PASS BY REFERENCE. The two word arrays to compare
|
---|
1327 | ;" DivStr -- OPTIONAL, the character to use to separate the answers
|
---|
1328 | ;" in the return string. Default is '^'
|
---|
1329 | ;"Note: The words in DiffStr are divided by "|"
|
---|
1330 | ;"Results: DiffStr1A>DiffStr1B^pos1>pos2^DiffStr2A>DiffStr2B^pos1>pos2^...
|
---|
1331 | ;" The A DiffStr would be what the value is in Words1, and
|
---|
1332 | ;" the B DiffStr would be what the value is in Words2, or @ if deleted.
|
---|
1333 |
|
---|
1334 | set DivChr=$get(DivChr,"^")
|
---|
1335 | new result set result=""
|
---|
1336 | new trimmed1,trimmed2 set trimmed1=0,trimmed2=0
|
---|
1337 | new p1,p2,matchStr,matchLen
|
---|
1338 | new diffStr1,diffStr2,temp
|
---|
1339 | new tWords1,tWords2
|
---|
1340 | merge tWords1=Words1
|
---|
1341 | merge tWords2=Words2
|
---|
1342 | new i,len1,len2,trimLen1,trimLen2
|
---|
1343 | new diffPos1,diffPos2
|
---|
1344 | set len1=+$get(tWords1("MAXNODE"))
|
---|
1345 | set len2=+$get(tWords2("MAXNODE"))
|
---|
1346 | DWLoop
|
---|
1347 | set temp=$$SimWPos(.tWords1,.tWords2,DivChr,.p1,.p2,.matchStr)
|
---|
1348 | ;"Returns: Pos1^Pos2^MatchStr Pos1=pos in s1, Pos2=pos in s2, MatchStr=the matching Str
|
---|
1349 |
|
---|
1350 | ;"Possible return options:
|
---|
1351 | ;" p1=p2=0 -- two strings have nothing in common
|
---|
1352 | ;" p1=p2=1 -- first word of each string is the same
|
---|
1353 | ;" p1=p2=X -- words 1..(X-1) differ from each other.
|
---|
1354 | ;" p1>p2 -- e.g. EXT REL TAB --> XR TAB
|
---|
1355 | ;" p1<p2 -- XR TAB --> EXT REL TAB
|
---|
1356 |
|
---|
1357 | if (p1=0)&(p2=0) do
|
---|
1358 | . set diffStr1=$$CatArray(.tWords1,1,len1,"|")
|
---|
1359 | . set diffStr2=$$CatArray(.tWords2,1,len2,"|")
|
---|
1360 | . set trimLen1=len1,trimLen2=len2
|
---|
1361 | . set diffPos1=1+trimmed1
|
---|
1362 | . set diffPos2=1+trimmed2
|
---|
1363 | else if (p1=1)&(p2=1) do
|
---|
1364 | . set diffStr1="@",diffStr2="@"
|
---|
1365 | . set trimLen1=1,trimLen2=1
|
---|
1366 | . set diffPos1=0,diffPos2=0
|
---|
1367 | else do
|
---|
1368 | . set diffStr1=$$CatArray(.tWords1,1,p1-1,"|")
|
---|
1369 | . set diffStr2=$$CatArray(.tWords2,1,p2-1,"|")
|
---|
1370 | . set trimLen1=p1-1,trimLen2=p2-1
|
---|
1371 | . set diffPos1=1+trimmed1,diffPos2=1+trimmed2
|
---|
1372 |
|
---|
1373 | if diffStr1="" set diffStr1="@"
|
---|
1374 | if diffStr2="" set diffStr2="@"
|
---|
1375 |
|
---|
1376 | if '((diffStr1="@")&(diffStr1="@")) do
|
---|
1377 | . set:(result'="")&($extract(result,$length(result))'=DivChr) result=result_DivChr
|
---|
1378 | . set result=result_diffStr1_">"_diffStr2_DivChr
|
---|
1379 | . set result=result_diffPos1_">"_diffPos2
|
---|
1380 |
|
---|
1381 | do ListTrim^TMGMISC("tWords1",1,trimLen1,"MAXNODE")
|
---|
1382 | do ListTrim^TMGMISC("tWords2",1,trimLen2,"MAXNODE")
|
---|
1383 | set trimmed1=trimmed1+trimLen1
|
---|
1384 | set trimmed2=trimmed2+trimLen2
|
---|
1385 |
|
---|
1386 | if ($get(tWords1("MAXNODE"))=0)&($get(tWords2("MAXNODE"))=0) goto DWDone
|
---|
1387 | goto DWLoop
|
---|
1388 |
|
---|
1389 | DWDone
|
---|
1390 | quit result
|
---|
1391 |
|
---|
1392 | CatArray(Words,i1,i2,DivChr)
|
---|
1393 | ;"Purpose: For given word array, return contatenated results from index1 to index2
|
---|
1394 | ;"Input: Words -- PASS BY REFERENCE. Array of Words, as might be created by CleaveToArray
|
---|
1395 | ;" i1 -- the index to start concat at
|
---|
1396 | ;" i2 -- the last index to include in concat
|
---|
1397 | ;" DivChr -- OPTIONAL. The character to used to separate words. Default=" "
|
---|
1398 |
|
---|
1399 | new result set result=""
|
---|
1400 | set DivChr=$get(DivChr," ")
|
---|
1401 | new i for i=i1:1:i2 do
|
---|
1402 | . new word set word=$get(Words(i))
|
---|
1403 | . if word="" quit
|
---|
1404 | . set:(result'="")&($extract(result,$length(result))'=DivChr) result=result_DivChr
|
---|
1405 | . set result=result_word
|
---|
1406 | quit result
|
---|
1407 |
|
---|
1408 | QTPROTECT(S) ;"SAAC compliant entry point
|
---|
1409 | quit $$QtProtect(.S)
|
---|
1410 | QtProtect(s)
|
---|
1411 | ;"Purpose: Protects quotes by converting all quotes do double quotes (" --> "")
|
---|
1412 | ;"Input : s -- The string to be modified. Original string is unchanged.
|
---|
1413 | ;"Result: returns a string with all instances of single instances of quotes
|
---|
1414 | ;" being replaced with two quotes.
|
---|
1415 |
|
---|
1416 | new tempS
|
---|
1417 | set tempS=$$Substitute($get(s),"""""","<^@^>") ;"protect original double quotes
|
---|
1418 | set tempS=$$Substitute(tempS,"""","""""")
|
---|
1419 | set tempS=$$Substitute(tempS,"<^@^>","""""") ;"reverse protection
|
---|
1420 | quit tempS
|
---|
1421 |
|
---|
1422 |
|
---|
1423 | GetStrPos(s,StartPos,P1,P2) ;"INCOMPLETE!!
|
---|
1424 | ;"Purpose: return position of start and end of a string (marked by starting
|
---|
1425 | ;" and ending quote. Search is started at StartPos.
|
---|
1426 | ;" Example: if s='She said "Hello" to Bill', and StartPos=1
|
---|
1427 | ;" then P1 should be returned as 10, and P2 as 16
|
---|
1428 | ;"Input: s -- the text to be
|
---|
1429 | ;" StartPos -- the position to start the search at. Optional: default=1
|
---|
1430 | ;" P1 -- PASS BY REFERENCE, an Out Parameter
|
---|
1431 | ;" P2 -- PASS BY REFERENCE, an Out Parameter
|
---|
1432 | ;"Results: None
|
---|
1433 | ;"Output: P1 and P2 are returned as per example above, or 0 if not quotes in text
|
---|
1434 |
|
---|
1435 | set P1=0,P2=0
|
---|
1436 | if s'["""" goto GSPDone
|
---|
1437 | set StartPos=+$get(StartPos,1)
|
---|
1438 | new tempS set tempS=$extract(s,StartPos,$length(s))
|
---|
1439 | set tempS=$$Substitute(tempS,"""""",$char(1)_$char(1))
|
---|
1440 |
|
---|
1441 | ;"FINISH... NOT COMPLETED...
|
---|
1442 | GSPDone
|
---|
1443 | quit
|
---|
1444 |
|
---|
1445 | InQt(s,Pos)
|
---|
1446 | ;"Purpose: to return if a given character, in string(s), is insided quotes
|
---|
1447 | ;" e.g. s='His name is "Bill," OK?' and if p=14, then returns 1
|
---|
1448 | ;" (note the above string is usually stored as:
|
---|
1449 | ;" "His name is ""Bill,"" OK?" in the text editor, BUT in the
|
---|
1450 | ;" strings that will be passed here I will get only 1 quote character
|
---|
1451 | ;"Input: s -- the string to scan
|
---|
1452 | ;" Pos -- the position of the character in question
|
---|
1453 | ;"Results: 0 if not inside quotes, 1 if it is.
|
---|
1454 | ;"NOTE: if Pos points to the bounding quotes, the result is 0
|
---|
1455 | new inQt set inQt=0
|
---|
1456 | if (Pos>$length(s))!(Pos<1) goto IQtDone
|
---|
1457 | new p set p=$find(s,"""")-1
|
---|
1458 | if p<Pos for p=p-1:1:Pos set:($extract(s,p)="""") inQt='inQt
|
---|
1459 | IQtDone quit inQt
|
---|
1460 |
|
---|
1461 | HNQTSUB(s,SubStr) ;"A ALL CAPS ENTRY POINT
|
---|
1462 | quit $$HasNonQtSub(.s,.SubStr)
|
---|
1463 | HasNonQtSub(s,SubStr)
|
---|
1464 | ;"Purpose: Return if string S contains SubStr, not inside quotes.
|
---|
1465 | new Result set Result=0
|
---|
1466 | if s'[SubStr goto HNQCDn
|
---|
1467 | new p set p=1
|
---|
1468 | new done set done=0
|
---|
1469 | new instance set instance=0
|
---|
1470 | for do quit:(done=1)
|
---|
1471 | . set instance=instance+1
|
---|
1472 | . set p=$$Pos(SubStr,s,instance)
|
---|
1473 | . if p=0 set done=1 quit
|
---|
1474 | . if $$InQt(.s,p)=0 set Result=1,done=1 quit
|
---|
1475 | HNQCDn quit Result
|
---|
1476 |
|
---|
1477 | GetWord(s,Pos,OpenDiv,CloseDiv)
|
---|
1478 | ;"Purpose: Extract a word from a sentance, bounded by OpenDiv,CloseDiv
|
---|
1479 | ;"Example: s="The cat is hungry", Pos=14 --> returns "hungry"
|
---|
1480 | ;"Example: s="Find('Purple')", Pos=8, OpenDiv="(", CloseDiv=")" --> returns "'Purple'"
|
---|
1481 | ;"Input: s -- the string containing the source sentence
|
---|
1482 | ;" Pos -- the index of a character anywhere inside desired word.
|
---|
1483 | ;" OpenDiv -- OPTIONAL, default is " " this is what marks the start of the word.
|
---|
1484 | ;" NOTE: if $length(OpenDiv)>1, then OpenDiv is considered
|
---|
1485 | ;" to be a SET of characters, any of which can be used
|
---|
1486 | ;" as a opening character.
|
---|
1487 | ;" CloseDiv -- OPTIONAL, default is " " this is what marks the end of the word.
|
---|
1488 | ;" NOTE: if $length(CloseDiv)>1, then CloseDiv is considered
|
---|
1489 | ;" to be a SET of characters, any of which can be used
|
---|
1490 | ;" as a closing character.
|
---|
1491 | ;"Results: returns desired word, or "" if problem.
|
---|
1492 | ;
|
---|
1493 | new result set result=""
|
---|
1494 | set OpenDiv=$get(OpenDiv," ")
|
---|
1495 | set CloseDiv=$get(CloseDiv," ")
|
---|
1496 | set Pos=+$get(Pos) if Pos'>0 goto GWdDone
|
---|
1497 | new p1,p2,len,i
|
---|
1498 | set len=$length(s)
|
---|
1499 | for p2=Pos:1:len if CloseDiv[$extract(s,p2) set p2=p2-1 quit
|
---|
1500 | for p1=Pos:-1:1 if OpenDiv[$extract(s,p1) set p1=p1+1 quit
|
---|
1501 | set result=$extract(s,p1,p2)
|
---|
1502 | GWdDone quit result
|
---|
1503 |
|
---|
1504 | MATCHXTR(s,DivCh,Group,Map,Restrict)
|
---|
1505 | ;"Purpose: Provide a SAAC compliant (all upper case) entry point) for MatchXtract
|
---|
1506 | quit $$MatchXtract(.s,.DivCh,.Group,.Map,.Restrict)
|
---|
1507 | ;
|
---|
1508 | MatchXtract(s,DivCh,Group,Map,Restrict)
|
---|
1509 | ;"Purpose to extract a string bounded by DivCh, honoring matching encapsulators
|
---|
1510 | ;"Note: the following markers are honored as paired encapsulators:
|
---|
1511 | ;" ( ), { }, | |, < >, # #, [ ],
|
---|
1512 | ;" To specify which set to use, DivCh should specify only OPENING character
|
---|
1513 | ;"E.g. DivCh="{"
|
---|
1514 | ;" s="Hello {There}" --> return "There"
|
---|
1515 | ;" s="Hello {There {nested braces} friend}" --> return "There {nested braces} friend"
|
---|
1516 | ;" DivCh="|"
|
---|
1517 | ;" s="Hello |There|" --> "There"
|
---|
1518 | ;" s="Hello |There{|friend|}|" --> "There{|friend|}"
|
---|
1519 | ;" Notice that the second "|" was not paired to the first, because an opening brace was first.
|
---|
1520 | ;"Input: s -- The string to evaluate
|
---|
1521 | ;" DivCh -- The opening character of the encapsulator to use
|
---|
1522 | ;" Group -- OPTIONAL. Default is 1. If line has more than one set of encapsulated entries, which group to get from
|
---|
1523 | ;" Map -- OPTIONAL. PASS BY REFERENCE. If function is to be called multiple times,
|
---|
1524 | ;" then a prior Map variable can be passed to speed processing.
|
---|
1525 | ;" Restrict -- OPTIONAL. A string of allowed opening encapsulators (allows others to be ignored)
|
---|
1526 | ;" e.g. "{(|" <-- will cause "<>#[]" to be ignored
|
---|
1527 | ;"Results: Returns extracted string.
|
---|
1528 | if $data(Map)=0 do MapMatch(s,.Map,.Restrict)
|
---|
1529 | set Group=$get(Group,1)
|
---|
1530 | set DivCh=$get(DivCh)
|
---|
1531 | new Result set Result=""
|
---|
1532 | new i set i=0
|
---|
1533 | for set i=$order(Map(Group,i)) quit:(i="")!(Result'="") do
|
---|
1534 | . if DivCh'=$get(Map(Group,i)) quit
|
---|
1535 | . new p,j
|
---|
1536 | . for j=1,2 set p(j)=+$get(Map(Group,i,"Pos",j))
|
---|
1537 | . set Result=$extract(s,p(1)+1,p(2)-1)
|
---|
1538 | quit Result
|
---|
1539 |
|
---|
1540 | MapMatch(s,Map,Restrict)
|
---|
1541 | ;"Purpose to map a string with nested braces, parentheses etc (encapsulators)
|
---|
1542 | ;"Note: the following markers are honored as paired encapsulators:
|
---|
1543 | ;" ( ), { }, | |, < >, # #, " "
|
---|
1544 | ;"Input: s -- string to evaluate
|
---|
1545 | ;" Map -- PASS BY REFERENCE. An OUT PARAMETER. Prior values are killed. Format:
|
---|
1546 | ;" Map(Group,Depth)=OpeningSymbol
|
---|
1547 | ;" Map(Group,Depth,"Pos",1)=index of opening symbol
|
---|
1548 | ;" Map(Group,Depth,"Pos",2)=index of paired closing symbol
|
---|
1549 | ;" Restrict -- OPTIONAL. A string of allowed opening encapsulators (allows others to be ignored)
|
---|
1550 | ;" e.g. "{(|" <-- will cause "<>#[]" to be ignored
|
---|
1551 | ;"E.g. s="Hello |There{|friend|}|"
|
---|
1552 | ;" Map(1,1)="|"
|
---|
1553 | ;" Map(1,1,"Pos",1)=7
|
---|
1554 | ;" Map(1,1,"Pos",2)=23
|
---|
1555 | ;" Map(1,2)="{"
|
---|
1556 | ;" Map(1,2,"Pos",1)=13
|
---|
1557 | ;" Map(1,2,"Pos",2)=22
|
---|
1558 | ;" Map(1,3)="|"
|
---|
1559 | ;" Map(1,3,"Pos",1)=14
|
---|
1560 | ;" Map(1,3,"Pos",2)=21
|
---|
1561 | ;"Eg. s="Hello |There{|friend|}| This is more (and I (want { to say} !) OK?)"
|
---|
1562 | ;" map(1,1)="|"
|
---|
1563 | ;" map(1,1,"Pos",1)=7
|
---|
1564 | ;" map(1,1,"Pos",2)=23
|
---|
1565 | ;" map(1,2)="{"
|
---|
1566 | ;" map(1,2,"Pos",1)=13
|
---|
1567 | ;" map(1,2,"Pos",2)=22
|
---|
1568 | ;" map(1,3)="|"
|
---|
1569 | ;" map(1,3,"Pos",1)=14
|
---|
1570 | ;" map(1,3,"Pos",2)=21
|
---|
1571 | ;" map(2,1)="("
|
---|
1572 | ;" map(2,1,"Pos",1)=39
|
---|
1573 | ;" map(2,1,"Pos",2)=68
|
---|
1574 | ;" map(2,2)="("
|
---|
1575 | ;" map(2,2,"Pos",1)=46
|
---|
1576 | ;" map(2,2,"Pos",2)=63
|
---|
1577 | ;" map(2,3)="{"
|
---|
1578 | ;" map(2,3,"Pos",1)=52
|
---|
1579 | ;" map(2,3,"Pos",2)=60
|
---|
1580 | ;"Results: none
|
---|
1581 | set Restrict=$get(Restrict,"({|<#""")
|
---|
1582 | new Match,Depth,i,Group
|
---|
1583 | if Restrict["(" set Match("(")=")"
|
---|
1584 | if Restrict["{" set Match("{")="}"
|
---|
1585 | if Restrict["|" set Match("|")="|"
|
---|
1586 | if Restrict["<" set Match("<")=">"
|
---|
1587 | if Restrict["#" set Match("#")="#"
|
---|
1588 | if Restrict["""" set Match("""")=""""
|
---|
1589 | kill Map
|
---|
1590 | set Depth=0,Group=1
|
---|
1591 | for i=1:1:$length(s) do
|
---|
1592 | . new ch set ch=$extract(s,i)
|
---|
1593 | . if ch=$get(Map(Group,Depth,"Closer")) do quit
|
---|
1594 | . . set Map(Group,Depth,"Pos",2)=i
|
---|
1595 | . . kill Map(Group,Depth,"Closer")
|
---|
1596 | . . set Depth=Depth-1
|
---|
1597 | . . if Depth=0 set Group=Group+1
|
---|
1598 | . if $data(Match(ch))=0 quit
|
---|
1599 | . set Depth=Depth+1
|
---|
1600 | . set Map(Group,Depth)=ch
|
---|
1601 | . set Map(Group,Depth,"Closer")=Match(ch)
|
---|
1602 | . set Map(Group,Depth,"Pos",1)=i
|
---|
1603 | quit
|
---|
1604 |
|
---|
1605 | CmdChStrip(s)
|
---|
1606 | ;"Purpose: Strip all characters < #32 from string.
|
---|
1607 | new Codes,i,result
|
---|
1608 | set Codes=""
|
---|
1609 | for i=1:1:31 set Codes=Codes_$char(i)
|
---|
1610 | set result=$translate(s,Codes,"")
|
---|
1611 | quit result
|
---|
1612 |
|
---|
1613 | StrBounds(s,p)
|
---|
1614 | ;"Purpose: given position of start of string, returns index of end of string
|
---|
1615 | ;"Input: s -- the string to eval
|
---|
1616 | ;" p -- the index of the start of the string
|
---|
1617 | ;"Results : returns the index of the end of the string, or 0 if not found.
|
---|
1618 | new result set result=0
|
---|
1619 | for p=p+1:1 quit:(p>$length(s))!(result>0) do
|
---|
1620 | . if $extract(s,p)'="""" quit
|
---|
1621 | . set p=p+1
|
---|
1622 | . if $extract(s,p)="""" quit
|
---|
1623 | . set result=p-1
|
---|
1624 | quit result
|
---|
1625 |
|
---|
1626 | NonWhite(s,p)
|
---|
1627 | ;"Purpose: given starting position, return index of first non-whitespace character
|
---|
1628 | ;" Note: either a " " or a TAB [$char(9)] will be considered a whitespace char
|
---|
1629 | ;"result: returns index if non-whitespace, or index past end of string if none found.
|
---|
1630 | new result,ch,done
|
---|
1631 | for result=p:1 quit:(result>$length(s)) do quit:done
|
---|
1632 | . set ch=$extract(s,result)
|
---|
1633 | . set done=(ch'=" ")&(ch'=$char(9))
|
---|
1634 | quit result
|
---|
1635 |
|
---|
1636 | Pad2Pos(Pos,ch)
|
---|
1637 | ;"Purpose: return a string that can be used to pad from the current $X
|
---|
1638 | ;" screen cursor position, up to Pos, using char Ch (optional)
|
---|
1639 | ;"Input: Pos -- a screen X cursor position, i.e. from 1-80 etc (depending on screen width)
|
---|
1640 | ;" ch -- Optional, default is " "
|
---|
1641 | ;"Result: returns string of padded characters.
|
---|
1642 | new width set width=+$get(Pos)-$X if width'>0 set width=0
|
---|
1643 | quit $$LJ^XLFSTR("",width,.ch)
|
---|
1644 |
|
---|
1645 | HTML2TXT(Array)
|
---|
1646 | ;"Purpose: text a WP array that is HTML formatted, and strip <P>, and
|
---|
1647 | ;" return in a format of 1 line per array node.
|
---|
1648 | ;"Input: Array -- PASS BY REFERENCE. This array will be altered.
|
---|
1649 | ;"Results: none
|
---|
1650 | ;"NOTE: This conversion causes some loss of HTML tags, so a round trip
|
---|
1651 | ;" conversion back to HTML would fail.
|
---|
1652 | ;"Called from: TMGTIUOJ.m
|
---|
1653 |
|
---|
1654 | new outArray,outI
|
---|
1655 | set outI=1
|
---|
1656 |
|
---|
1657 | ;"Clear out confusing non-breaking spaces.
|
---|
1658 | new spec
|
---|
1659 | set spec(" ")=" "
|
---|
1660 | set spec("<")="<"
|
---|
1661 | set spec(">")=">"
|
---|
1662 | set spec("&")="&"
|
---|
1663 | set spec(""")=""""
|
---|
1664 | new line set line=0
|
---|
1665 | for set line=$order(Array(line)) quit:(line="") do
|
---|
1666 | . new lineS set lineS=$get(Array(line,0))
|
---|
1667 | . set Array(line,0)=$$REPLACE^XLFSTR(lineS,.spec)
|
---|
1668 |
|
---|
1669 | new s2 set s2=""
|
---|
1670 | new line set line=0
|
---|
1671 | for set line=$order(Array(line)) quit:(line="") do
|
---|
1672 | . new lineS set lineS=s2_$get(Array(line,0))
|
---|
1673 | . set s2=""
|
---|
1674 | . for do quit:(lineS'["<")
|
---|
1675 | . . if (lineS["<P>")&($piece(lineS,"<P>",1)'["<BR>") do quit
|
---|
1676 | . . . set outArray(outI,0)=$piece(lineS,"<P>",1)
|
---|
1677 | . . . set outI=outI+1
|
---|
1678 | . . . set outArray(outI,0)="" ;"Add blank line to create paragraph break.
|
---|
1679 | . . . set outI=outI+1
|
---|
1680 | . . . set lineS=$piece(lineS,"<P>",2,999)
|
---|
1681 | . . if (lineS["</P>")&($piece(lineS,"</P>",1)'["<BR>") do quit
|
---|
1682 | . . . set outArray(outI,0)=$piece(lineS,"</P>",1)
|
---|
1683 | . . . set outI=outI+1
|
---|
1684 | . . . set outArray(outI,0)="" ;"Add blank line to create paragraph break.
|
---|
1685 | . . . set outI=outI+1
|
---|
1686 | . . . set lineS=$piece(lineS,"</P>",2,999)
|
---|
1687 | . . if (lineS["</LI>")&($piece(lineS,"</LI>",1)'["<BR>") do quit
|
---|
1688 | . . . set outArray(outI,0)=$piece(lineS,"</LI>",1) ;" _"</LI>"
|
---|
1689 | . . . set outI=outI+1
|
---|
1690 | . . . set outArray(outI,0)="" ;"Add blank line to create paragraph break.
|
---|
1691 | . . . set outI=outI+1
|
---|
1692 | . . . set lineS=$piece(lineS,"</LI>",2,999)
|
---|
1693 | . . if lineS["<BR>" do quit
|
---|
1694 | . . . set outArray(outI,0)=$piece(lineS,"<BR>",1)
|
---|
1695 | . . . set outI=outI+1
|
---|
1696 | . . . set lineS=$piece(lineS,"<BR>",2,999)
|
---|
1697 | . . set s2=lineS,lineS=""
|
---|
1698 | . set s2=s2_lineS
|
---|
1699 | if s2'="" do
|
---|
1700 | . set outArray(outI,0)=s2
|
---|
1701 | . set outI=outI+1
|
---|
1702 |
|
---|
1703 | kill Array
|
---|
1704 | merge Array=outArray
|
---|
1705 | quit
|
---|
1706 |
|
---|
1707 |
|
---|
1708 | TrimTags(lineS)
|
---|
1709 | ;"Purpose: To cut out HTML tags (e.g. <...>) from lineS, however, <no data> is protected
|
---|
1710 | ;"Input: lineS : the string to work on.
|
---|
1711 | ;"Results: the modified string
|
---|
1712 | ;"Called from: TMGTIUOJ.m
|
---|
1713 | new result,key,spec
|
---|
1714 | set spec("<no data>")="[no data]"
|
---|
1715 | set result=$$REPLACE^XLFSTR(lineS,.spec)
|
---|
1716 | for quit:((result'["<")!(result'[">")) do
|
---|
1717 | . new partA,partB
|
---|
1718 | . set partA=$piece(result,"<",1)
|
---|
1719 | . new temp set temp=$extract(result,$length(partA)+1,999)
|
---|
1720 | . set partB=$piece(temp,">",2,99)
|
---|
1721 | . set result=partA_partB
|
---|
1722 | quit result
|
---|
1723 |
|
---|
1724 | IsHTML(IEN8925)
|
---|
1725 | ;"Purpose: to specify if the text held in the REPORT TEXT field is HTML markup
|
---|
1726 | ;"Input: IEN8925 -- record number in file 8925
|
---|
1727 | ;"Results: 1 if HTML markup, 0 otherwise.
|
---|
1728 | ;"Note: This is not a perfect test.
|
---|
1729 | ;
|
---|
1730 | new result set result=0
|
---|
1731 | new Done set Done=0
|
---|
1732 | new line set line=0
|
---|
1733 | for set line=$order(^TIU(8925,IEN8925,"TEXT",line)) quit:(line="")!Done do
|
---|
1734 | . new lineS set lineS=$$UP^XLFSTR($get(^TIU(8925,IEN8925,"TEXT",line,0)))
|
---|
1735 | . if (lineS["<!DOCTYPE HTML")!(lineS["<HTML>") set Done=1,result=1 quit
|
---|
1736 | quit result
|
---|
1737 |
|
---|