OSDN Git Service

c467126f1d9bb33ef03423422a36e7ede1f45fac
[winmerge-jp/winmerge-jp.git] / Plugins / dlls / editor addin.sct
1 <scriptlet>
2
3 <implements type="Automation" id="dispatcher">
4         <property name="PluginEvent">
5                 <get/>
6         </property>
7         <property name="PluginDescription">
8                 <get/>
9         </property>
10         <property name="PluginExtendedProperties">
11                 <get/>
12         </property>
13         <property name="PluginFileFilters">
14                 <get/>
15         </property>
16         <property name="PluginArguments">
17                 <get/>
18                 <put/>
19         </property>
20         <property name="PluginVariables">
21                 <get/>
22                 <put/>
23         </property>
24         <method name="ExecFilterCommand"/>
25         <method name="MakeUpper"/>
26         <method name="MakeLower"/>
27         <method name="RemoveDuplicates"/>
28         <method name="CountDuplicates"/>
29         <method name="SortAscending"/>
30         <method name="SortDescending"/>
31         <method name="ReverseColumns"/>
32         <method name="ReverseLines"/>
33         <method name="SelectColumns"/>
34         <method name="SelectLines"/>
35         <method name="Replace" internalName="ReplaceText"/>
36         <method name="Tokenize"/>
37         <method name="Trim"/>
38 </implements>
39
40 <script language="VBS">
41 Option Explicit
42
43 Const WinMergeRegKeyPath = "HKCU\Software\Thingamahoochie\WinMerge\"
44 Const PluginRegKeyPath = "HKCU\Software\Thingamahoochie\WinMerge\Plugins\editor addin.sct\"
45
46 Dim wsh: Set wsh = CreateObject("WScript.Shell")
47 Dim arguments: arguments = ""
48 Dim variables: variables = Array()
49
50 Function get_PluginEvent()
51         get_PluginEvent = "EDITOR_SCRIPT"
52 End Function
53
54 Function get_PluginDescription()
55         get_PluginDescription = "Basic text functions for the context menu"
56 End Function
57
58 Function get_PluginFileFilters()
59         get_PluginFileFilters= ".*"
60 End Function
61
62 Function get_PluginExtendedProperties()
63         get_PluginExtendedProperties = _
64         "GenerateUnpacker;" & _
65         "MakeUpper.MenuCaption=Make Uppercase;" & _
66         "MakeUpper.Description=Make selection uppercase;" & _
67         "MakeLower.MenuCaption=Make Lowercase;" & _
68         "MakeLower.Description=Make selection lowercase;" & _
69         "RemoveDuplicates.MenuCaption=Remove Duplicate Lines;" & _
70         "RemoveDuplicates.Description=Remove duplicate lines;" & _
71         "CountDuplicates.MenuCaption=Count Duplicate Lines;" & _
72         "CountDuplicates.Description=Count duplicate lines;" & _
73         "SortAscending.MenuCaption=Sort Lines Ascending;" & _
74         "SortAscending.Description=Sort lines Ascending;" & _
75         "SortDescending.MenuCaption=Sort Lines Descending;" & _
76         "SortDescending.Description=Sort lines descending;" & _
77         "ExecFilterCommand.MenuCaption=Apply Filter Command...;" & _
78         "ExecFilterCommand.Description=Apply filter command. " & vbCrLf & _
79                 "Arguments: filter command. %1 is replaced with the file name.;" & _
80         "ExecFilterCommand.ArgumentsRequired;" & _
81         "Tokenize.MenuCaption=Tokenize...;" & _
82         "Tokenize.Description=Tokenize selection. " & vbCrLf & _
83                 "Arguments: a regular expression for tokenizing. (e.g. [^\w]+);" & _
84         "Tokenize.ArgumentsRequired;" & _
85         "Trim.MenuCaption=Trim Spaces;" & _
86         "Trim.Description=Trim spaces;" & _
87         "SelectColumns.MenuCaption=Select Columns...;" & _
88         "SelectColumns.Description=Select some columns." & vbCrLf & _
89                 "Arguments: list of column ranges to select. (e.g. -3,5-10,30-) or regular expression;" & _
90         "SelectColumns.ArgumentsRequired;" & _
91         "SelectLines.MenuCaption=Select Lines...;" & _
92         "SelectLines.Description=Select some lines." & vbCrLf & _
93                 "Arguments: list of line ranges to select. (e.g. -3,5-10,30-) or regular expression;" & _
94         "SelectLines.ArgumentsRequired;" & _
95         "ReverseColumns.MenuCaption=Reverse Columns;" & _
96         "ReverseColumns.Description=Reverse columns;" & _
97         "ReverseLines.MenuCaption=Reverse Lines;" & _
98         "ReverseLines.Description=Reverse lines;" & _
99         "Replace.MenuCaption=Replace...;" & _
100         "Replace.Description=Replace text with another text." & vbCrLf & _
101                 "Arguments: search text and replacement text;" & _
102         "Replace.ArgumentsRequired;"
103 End Function
104
105 Function get_PluginArguments()
106         get_PluginArguments = arguments
107 End Function
108
109 Sub put_PluginArguments(NewValue)
110         arguments = NewValue
111 End Sub
112
113 Function get_PluginVariables()
114         get_PluginVariables = Join(variables, Chr(0))
115 End Function
116
117 Sub put_PluginVariables(NewValue)
118         variables = Split(NewValue, Chr(0))
119 End Sub
120
121 Function regRead(Key, DefaultValue)
122         regRead = DefaultValue
123         On Error Resume Next
124         regRead = wsh.RegRead(Key)
125 End Function
126
127 Function IsLangJapanese()
128         Dim languageId
129         On Error Resume Next
130         languageId = CLng(regRead(WinMergeRegKeyPath & "Locale\LanguageId", 1033))
131         IsLangJapanese = (languageId = 1041)
132 End Function
133
134 Function ReplaceVariables(str)
135         Dim newstr
136         Dim pos
137         Dim foundpos
138         Dim ch
139         pos = 1
140         Do While True
141                 foundpos = InStr(pos, str, "%")
142                 If foundpos > 0 Then
143                         ch = Mid(str, foundpos + 1, 1)
144                         If ch = "%" Then
145                                 newstr = newstr & "%"
146                                 pos = foundpos + 2
147                         ElseIf IsNumeric(ch) Then
148                                 newstr = newstr & Mid(str, pos, foundpos - pos)
149                                 If CLng(ch) <= SafeUBound(variables) Then
150                                         newstr = newstr & variables(CLng(ch))
151                                 End If
152                                 pos = foundpos + 2
153                         Else
154                                 newstr = newstr & Mid(str, pos, foundpos - pos + 1)
155                                 pos = foundpos + 1
156                         End If
157                 Else
158                         newstr = newstr & Mid(str, pos)
159                         Exit Do
160                 End If
161         Loop
162         ReplaceVariables = newstr
163 End Function
164
165 Function IsFirstArgumentEmpty()
166         IsFirstArgumentEmpty = (Trim(arguments) = "")
167 End Function
168
169 Function SafeUBound(ary)
170         SafeUBound = -1
171         On Error Resume Next
172         SafeUBound = UBound(ary)
173 End Function
174
175 Function ParseArguments(args)
176         Dim ary()
177         Dim ch
178         Dim inQuotes
179         Dim token
180         Dim argsLen
181         Dim i, j
182         argsLen = Len(args)
183         For i = 1 To argsLen
184                 ch = Mid(args, i, 1)
185                 If Not inQuotes Then
186                         If ch = " " Or ch = vbTab Then
187                                 If len(token) > 0 Then
188                                         ReDim Preserve ary(j)
189                                         ary(j) = token
190                                         j = j + 1
191                                         token = ""
192                                 End If
193                         ElseIf ch = """" Then
194                                 inQuotes = True
195                         Else
196                                 token = token & ch
197                         End If
198                 Else
199                         If ch = """" Then
200                                 If i + 1 <= argsLen Then
201                                         If Mid(args, i + 1, 1) = """" Then
202                                                 token = token & ch
203                                         End if
204                                 End If
205                                 inQuotes = False 
206                         Else
207                                 token = token & ch
208                         End If
209                 End If
210         Next
211         If Len(token) > 0 Then
212                 ReDim Preserve ary(j)
213                 ary(j) = token
214                 j = j + 1
215                 token = ""
216         End If
217         ParseArguments = ary 
218 End Function
219
220 Function ParseRanges(rangeText)
221         Dim i, j
222         Dim ary, ary2, aryRanges()
223         Dim rangeFrom, rangeTo
224         ary = Split(rangeText, ",")
225         j = 0
226         For i = 0 To SafeUBound(ary)
227                 ary2 = Split(ary(i), "-")
228                 rangeFrom = ""
229                 If SafeUBound(ary2) >= 0 Then
230                         rangeFrom = Trim(ary2(0))
231                 End If
232                 rangeTo = rangeFrom
233                 If SafeUBound(ary2) > 0 Then
234                         rangeTo = Trim(ary2(1))
235                 End If
236                 If IsNumeric(rangeFrom) Or IsNumeric(rangeTo) Then
237                         If Not IsNumeric(rangeFrom) Then rangeFrom = 1
238                         If Not IsNumeric(rangeTo)   Then rangeTo   = 1000000000
239                         If CDbl(rangeFrom) < 1 Or CDbl(rangeFrom) > 1000000000 Then rangeFrom = 1
240                         If CDbl(rangeTo)   < 1 Or CDbl(rangeTo)   > 1000000000 Then rangeTo   = 1
241                         If CDbl(rangeFrom) > CDbl(rangeTo) Then rangeTo = rangeFrom
242                         Redim preserve aryRanges(j)
243                         aryRanges(j) = Array(CLng(rangeFrom), CLng(rangeTo))
244                         j = j + 1
245                 End If
246         Next
247         ParseRanges = aryRanges
248 End Function
249
250 Function ParseSelectColumnsLinesArguments(args, invert)
251         Dim rangesOrRegExps()
252         Dim argAry
253         Dim i, j
254         Dim re
255         Dim isOption
256         Set re = Nothing
257         argAry = ParseArguments(args)
258         invert = False
259         For i = 0 To SafeUBound(argAry)
260                 isOption = False
261                 If Len(argAry(i)) >= 2 Then
262                         Select Case Left(argAry(i), 1)
263                         Case "-", "/"
264                                 Select Case Mid(argAry(i), 2, 1)
265                                 Case "e", "i", "g"
266                                         isOption = True
267                                         If re Is Nothing Then
268                                                 Set re = New RegExp
269                                                 Redim Preserve rangesOrRegExps(j)
270                                                 Set rangesOrRegExps(j) = re
271                                                 j = j + 1
272                                         End If
273                                         If InStr(argAry(i), "i") > 0 Then
274                                                 re.IgnoreCase = True
275                                         End If
276                                         If InStr(argAry(i), "g") > 0 Then
277                                                 re.Global  = True
278                                         End If
279                                 Case "v"
280                                         isOption = True
281                                         invert = True
282                                 End Select
283                         End Select
284                 End If
285                 If Not isOption Then
286                         If Not (re Is Nothing) Then
287                                 re.Pattern = argAry(i)
288                                 Set re = Nothing
289                         Else
290                                 Redim Preserve rangesOrRegExps(j)
291                                 rangesOrRegExps(j) = ParseRanges(argAry(i))
292                                 If SafeUBound(rangesOrRegExps(j)) < 0 Then
293                                         Set rangesOrRegExps(j) = New RegExp
294                                         rangesOrRegExps(j).Pattern = argAry(i)
295                                 End If
296                                 j = j + 1
297                         End If
298                 End If
299         Next
300         ParseSelectColumnsLinesArguments = rangesOrRegExps
301 End Function
302
303 Function ParseReplaceArguments(args, regex, ignoreCase)
304         Dim patterns()
305         Dim argAry
306         Dim i, j
307         Dim re
308         Dim isOption
309         Set re = Nothing
310         argAry = ParseArguments(args)
311         regex = False
312         ignoreCase = False
313         For i = 0 To SafeUBound(argAry)
314                 isOption = False
315                 If Len(argAry(i)) >= 2 Then
316                         Select Case Left(argAry(i), 1)
317                         Case "-", "/"
318                                 Select Case Mid(argAry(i), 2, 1)
319                                 Case "e", "i"
320                                         isOption = True
321                                         regex = True
322                                         If InStr(argAry(i), "i") > 0 Then
323                                                 ignoreCase = True
324                                         End If
325                                 End Select
326                         End Select
327                 End If
328                 If Not isOption Then
329                         Redim Preserve patterns(j)
330                         patterns(j) = argAry(i)
331                         j = j + 1
332                 End If
333         Next
334         ParseReplaceArguments = patterns
335 End Function
336
337 Function SplitLines(text, eol)
338         Dim re, matches
339         Set re = New RegExp
340         re.Global = False
341         re.IgnoreCase = False
342         re.Pattern = "\r\n|\n|\r"
343         Set matches = re.Execute(text)
344         If matches.Count > 0 Then
345                 eol = matches(0).Value
346         End If
347         SplitLines = Split(text, eol)
348 End Function
349
350 ' transformation functions
351 Function MakeUpper(Text)
352         MakeUpper = UCase(Text)
353 End Function
354
355 Function MakeLower(Text)
356         MakeLower = LCase(Text)
357 End Function
358
359 Function ExecFilterCommand(Text)
360         Dim cmd
361         If IsFirstArgumentEmpty() Then
362                 cmd = regRead(PluginRegKeyPath & "ExecFilterCommand", "")
363                 If IsLangJapanese() Then
364                         cmd = InputBox("\83t\83B\83\8b\83^\83R\83}\83\93\83h\82ð\93ü\97Í\82µ\82Ä\82­\82¾\82³\82¢", "ExecFilterCommand", cmd)
365                 Else
366                         cmd = InputBox("Enter filter command", "ExecFilterCommand", cmd)
367                 End If
368                 If cmd <> "" Then
369                         wsh.RegWrite PluginRegKeyPath & "ExecFilterCommand", cmd
370                 End If
371                 cmd = ReplaceVariables(cmd)
372         Else
373                 cmd = arguments
374         End If
375         If cmd = "" Then
376                 If IsLangJapanese() Then
377                         Err.Raise 30001, , "\83L\83\83\83\93\83Z\83\8b\82³\82ê\82Ü\82µ\82½"
378                 Else
379                         Err.Raise 30001, , "Canceled"
380                 End If
381                 Exit Function
382         End If
383
384         On Error Resume Next
385
386         Dim path
387         path = wsh.ExpandEnvironmentStrings("%TEMP%\_winmerge_addin_temp_.txt")
388
389         Dim fso
390         Dim ts
391         Set fso = CreateObject("Scripting.FileSystemObject")
392         Set ts = fso.CreateTextFile(path)
393         If ts Is Nothing Then
394                 Exit Function
395         End If
396         ts.Write Text
397         ts.Close
398
399         Dim exe
400         Set exe = wsh.Exec("cmd /c type """ & path & """ | " & cmd & " 2>&1")
401         If exe Is Nothing Then
402                 If IsLangJapanese() Then
403                         MsgBox "\83R\83}\83\93\83h " & cmd & " \82Ì\8eÀ\8ds\82É\8e¸\94s\82µ\82Ü\82µ\82½:" & Err.Description 
404                 Else
405                         MsgBox "Failed to execute the command '" & cmd & "':" & Err.Description 
406                 End If
407                 fso.DeleteFile path
408                 Exit Function
409         End If
410
411         ExecFilterCommand = ""
412         Do Until exe.StdOut.AtEndOfStream
413                 ExecFilterCommand = ExecFilterCommand & exe.StdOut.ReadLine & vbCrLf
414         Loop
415
416         fso.DeleteFile path
417
418 End Function
419
420 Function SelectColumns(Text)
421         Dim args, ranges, regexpStr
422         Dim matches, m
423         Dim lines, eol, line
424         Dim i, j, k
425         Dim rangesOrRegExps
426         Dim invert
427         If IsFirstArgumentEmpty() Then
428                 args = regRead(PluginRegKeyPath & "SelectColumns", "")
429                 If IsLangJapanese() Then
430                         args = InputBox("\92\8a\8fo\82·\82é\97ñ\94Ô\8d\86\82Ì\94Í\88Í\82Ü\82½\82Í\90³\8bK\95\\8c»\82ð\8ew\92è\82µ\82Ä\82­\82¾\82³\82¢ (\97á: -3,5-10,30-)" & vbCrLf & "\82Ü\82½\82Í\92\8a\8fo\82µ\82½\82¢\95\8e\9a\97ñ\82É\83}\83b\83`\82·\82é\90³\8bK\95\\8c»\82ð\8ew\92è\82µ\82Ä\82­\82¾\82³\82¢:", "SelectColumns", ranges)
431                 Else
432                         args = InputBox("Enter the list of column ranges to select (e.g. -3,5-10,30-)" & vbCrLf & "or regular expression:", "SelectColumns", args)
433                 End If
434                 If args <> "" Then
435                         wsh.RegWrite PluginRegKeyPath & "SelectColumns", args
436                 End If
437         Else
438                 args = arguments
439         End If
440         If args = "" Then
441                 If IsLangJapanese() Then
442                         Err.Raise 30001, , "\83L\83\83\83\93\83Z\83\8b\82³\82ê\82Ü\82µ\82½"
443                 Else
444                         Err.Raise 30001, , "Canceled"
445                 End If
446                 Exit Function
447         End If
448         lines = SplitLines(Text, eol)
449         rangesOrRegExps = ParseSelectColumnsLinesArguments(args, invert)
450         For i = 0 To SafeUBound(lines)
451                 line = ""
452                 For j = 0 To SafeUBound(rangesOrRegExps)
453                         If IsArray(rangesOrRegExps(j)) Then
454                                 For k = 0 To SafeUBound(rangesOrRegExps(j))
455                                         If rangesOrRegExps(j)(k)(0) <= Len(lines(i)) Then
456                                                 line = line & Mid(lines(i), rangesOrRegExps(j)(k)(0), rangesOrRegExps(j)(k)(1) - rangesOrRegExps(j)(k)(0) + 1)
457                                         End If
458                                 Next
459                         Else
460                                 If Not invert Then
461                                         Set matches = rangesOrRegExps(j).Execute(lines(i))
462                                         For Each m In matches
463                                                 line = line & m.Value
464                                         Next
465                                 Else
466                                         line = line & rangesOrRegExps(j).Replace(lines(i), "")
467                                 End If
468                         End If
469                 Next
470                 lines(i) = line
471         Next
472         SelectColumns = Join(lines, eol)
473 End Function
474
475 Function SelectLines(Text)
476         Dim args, ranges
477         Dim matches, rangesOrRegExps
478         Dim lines, newlines(), eol
479         Dim i, j, k, l
480         Dim max
481         Dim matched
482         Dim invert
483         If IsFirstArgumentEmpty() Then
484                 args = regRead(PluginRegKeyPath & "SelectLines", "")
485                 If IsLangJapanese() Then
486                         args = InputBox("\92\8a\8fo\82·\82é\8ds\94Ô\8d\86\82Ì\94Í\88Í\82ð\8ew\92è\82µ\82Ä\82­\82¾\82³\82¢ (\97á: -3,5-10,30-)" & vbCrLf & "\82Ü\82½\82Í\81A\92\8a\8fo\82µ\82½\82¢\8ds\82É\83}\83b\83`\82·\82é\90³\8bK\95\\8c»\82ð\8ew\92è\82µ\82Ä\82­\82¾\82³\82¢:", "SelectLines", ranges)
487                 Else
488                         args = InputBox("Enter the list of line ranges to select (e.g. -3,5-10,30-)" & vbCrLf & "or regular expression:", "SelectLines", args)
489                 End If
490                 If args <> "" Then
491                         wsh.RegWrite PluginRegKeyPath & "SelectLines", args
492                 End If
493         Else
494                 args = arguments
495         End If
496         If args = "" Then
497                 If IsLangJapanese() Then
498                         Err.Raise 30001, , "\83L\83\83\83\93\83Z\83\8b\82³\82ê\82Ü\82µ\82½"
499                 Else
500                         Err.Raise 30001, , "Canceled"
501                 End If
502                 Exit Function
503         End If
504         lines = SplitLines(Text, eol)
505         l = 0
506         rangesOrRegExps = ParseSelectColumnsLinesArguments(args, invert)
507         For i = 0 To SafeUBound(rangesOrRegExps)
508                 If IsArray(rangesOrRegExps(i)) Then
509                         For j = 0 To SafeUBound(rangesOrRegExps(i))
510                                 max =rangesOrRegExps(i)(j)(1) - 1 
511                                 If max > SafeUBound(lines) Then max = SafeUBound(lines)
512                                 For k = rangesOrRegExps(i)(j)(0) - 1 To max
513                                         If k <= SafeUBound(lines) Then
514                                                 ReDim Preserve newlines(l)
515                                                 newlines(l) = lines(k)
516                                                 l = l + 1
517                                         End If
518                                 Next
519                         Next
520                 Else
521                         For j = 0 To SafeUBound(lines)
522                                 matched = rangesOrRegExps(i).Test(lines(j))
523                                 If invert Then matched = Not matched
524                                 If matched Then
525                                         ReDim Preserve newlines(l)
526                                         newlines(l) = lines(j)
527                                         l = l + 1
528                                 End If
529                         Next
530                 End If
531         Next
532         If SafeUBound(lines) >= 0 Then
533                 If lines(UBound(lines)) = "" Then
534                         If SafeUBound(newlines) >= 0 Then
535                                 If newlines(UBound(newlines)) <> "" Then
536                                         ReDim Preserve newlines(l)
537                                         newlines(l) = ""
538                                         l = l + 1
539                                 End If
540                         End If
541                 End If
542         End If
543         SelectLines = Join(newlines, eol)
544 End Function
545
546 Function ReplaceText(Text)
547         Dim args, patterns
548         Dim i
549         Dim re, regex
550         Dim ignoreCase
551         ReplaceText = Text
552         If IsFirstArgumentEmpty() Then
553                 args = regRead(PluginRegKeyPath & "Replace", "")
554                 If IsLangJapanese() Then
555                         args = InputBox("\8c\9f\8dõ\82·\82é\95\8e\9a\97ñ\82Æ\92u\8a·\82·\82é\95\8e\9a\97ñ\82ð\8ew\92è\82µ\82Ä\82­\82¾\82³\82¢:", "Replace", ranges)
556                 Else
557                         args = InputBox("Enter the search text and replacement text:", "Replace", args)
558                 End If
559                 If args <> "" Then
560                         wsh.RegWrite PluginRegKeyPath & "Replace", args
561                 End If
562         Else
563                 args = arguments
564         End If
565         If args = "" Then
566                 If IsLangJapanese() Then
567                         Err.Raise 30001, , "\83L\83\83\83\93\83Z\83\8b\82³\82ê\82Ü\82µ\82½"
568                 Else
569                         Err.Raise 30001, , "Canceled"
570                 End If
571                 Exit Function
572         End If
573         patterns = ParseReplaceArguments(args, regex, ignoreCase)
574         If regex Then
575                 For i = 0 To SafeUBound(patterns) Step 2
576                         Set re = New RegExp
577                         re.IgnoreCase = ignoreCase
578                         re.Global = True
579                         re.Multiline = True
580                         re.Pattern = patterns(i)
581                         If i + 1 <= UBound(patterns) Then
582                                 ReplaceText = re.Replace(ReplaceText, patterns(i + 1))
583                         Else
584                                 ReplaceText = re.Replace(ReplaceText, "")
585                         End If
586                 Next
587         Else
588                 For i = 0 To SafeUBound(patterns) Step 2
589                         If i + 1 <= UBound(patterns) Then
590                                 ReplaceText = Replace(ReplaceText, patterns(i), patterns(i + 1))
591                         Else
592                                 ReplaceText = Replace(ReplaceText, patterns(i), "")
593                         End If
594                 Next
595         End If
596 End Function
597
598 ' port from WinMerge2011
599 Function Tokenize(Text)
600         Dim pattern
601         If IsFirstArgumentEmpty() Then
602                 pattern = regRead(PluginRegKeyPath & "Tokenize", "")
603                 If IsLangJapanese() Then
604                         pattern = InputBox("\83g\81[\83N\83\93\95ª\8a\84\82·\82é\8bæ\90Ø\82è\82ð\90³\8bK\95\\8c»\82Å\93ü\97Í\82µ\82Ä\82­\82¾\82³\82¢ (\97á: [^\w]+):", "Tokenize", pattern)
605                 Else
606                         pattern = InputBox("Enter regex to tokenize (e.g. [^\w]+):", "Tokenize", pattern)
607                 End If
608                 If pattern <> "" Then
609                         wsh.RegWrite PluginRegKeyPath & "Tokenize", pattern
610                 End If
611         Else
612                 pattern = arguments
613         End If
614         If pattern = "" Then
615                 If IsLangJapanese() Then
616                         Err.Raise 30001, , "\83L\83\83\83\93\83Z\83\8b\82³\82ê\82Ü\82µ\82½"
617                 Else
618                         Err.Raise 30001, , "Canceled"
619                 End If
620                 Exit Function
621         End If
622         Dim re
623         Set re = New RegExp
624         re.Global = True
625         re.IgnoreCase = True
626         re.Pattern = pattern
627         Tokenize = re.Replace(Text, vbCrLf)
628 End Function
629
630 </script>
631
632 <script language="JScript">
633
634 function RemoveDuplicates(Text) {
635         var eol = Text.match(/\r\n|\n|\r/);
636         var lines = Text.split(eol);
637         var newlines = new Array();
638         var dic = {};
639         var lasteol = false;
640
641         if (!lines[lines.length - 1]) {
642                 lines.pop();
643                 lasteol = true;
644         }
645         for (var i = 0, j = 0; i < lines.length; i++) {
646                 var line = lines[i];
647                 if (typeof dic[line] === 'undefined') {
648                         dic[line] = 1;
649                         newlines[j] = line;
650                         j++;
651                 }
652         }
653         if (lasteol)
654                 newlines.push("");
655         return newlines.join(eol);
656 }
657
658 function CountDuplicates(Text) {
659         var eol = Text.match(/\r\n|\n|\r/);
660         var lines = Text.split(eol);
661         var newlines = new Array();
662         var dic = {};
663
664         if (!lines[lines.length - 1]) {
665                 lines.pop();
666         }
667         
668         for (var i = 0; i < lines.length; i++) {
669                 var line = lines[i];
670                 if (typeof dic[line] === 'undefined') {
671                         dic[line] = 1;
672                         newlines[j] = line;
673                         j++;
674                 } else {
675                         dic[line]++;
676                 }
677         }
678         var j = 0;
679         for (var line in dic) {
680                 newlines[j] = line + '\t' + dic[line];
681                 j++;
682         }
683         if (eol)
684                 newlines[j] = "";
685         return newlines.join(eol);
686 }
687
688 function ReverseColumns(Text) {
689         var eol = Text.match(/\r\n|\n|\r/);
690         var lines = Text.split(eol);
691         var lasteol = false;
692         if (!lines[lines.length - 1]) {
693                 lines.pop();
694                 lasteol = true;
695         }
696         for (var i = 0; i < lines.length; i++) {
697                 var line = lines[i];
698                 var newline = "";
699                 for (var j = 0; j < line.length; j++)
700                         newline += line.substr(line.length - j - 1, 1);
701                 lines[i] = newline;
702         }
703         if (lasteol)
704                 lines.push("");
705         return lines.join(eol);
706 }
707
708 function ReverseLines(Text) {
709         var eol = Text.match(/\r\n|\n|\r/);
710         var lines = Text.split(eol);
711         var lasteol = false;
712         if (!lines[lines.length - 1]) {
713                 lines.pop();
714                 lasteol = true;
715         }
716         var m = parseInt(lines.length / 2);
717         for (var i = 0; i < m; i++) {
718                 var line = lines[i];
719                 lines[i] = lines[lines.length - i - 1]
720                 lines[lines.length - i - 1] = line;
721         }
722         if (lasteol)
723                 lines.push("");
724         return lines.join(eol);
725 }
726
727 function SortAscending(Text) {
728         var eol = Text.match(/\r\n|\n|\r/);
729         var lines = Text.split(eol);
730
731         if (lines.length == 1) {
732                 return Text;
733         } else if (lines[lines.length - 1] == "") {
734                 lines.pop();
735                 return lines.sort().join(eol) + eol;
736         } else {
737                 return lines.sort().join(eol);
738         }
739 }
740
741 function SortDescending(Text) {
742         var eol = Text.match(/\r\n|\n|\r/);
743         var lines = Text.split(eol);
744
745         if (lines.length == 1) {
746                 return Text;
747         } else if (lines[lines.length - 1] == "") {
748                 lines.pop();
749                 lines.sort(function(a, b) { return a < b ? 1 : -1; });
750                 return lines.join(eol) + eol;
751         } else {
752                 return lines.sort(function(a, b) { return a < b ? 1 : -1; }).join(eol);
753         }
754 }
755
756 function Trim(Text) {
757         var eol = Text.match(/\r\n|\n|\r/);
758         var lines = Text.split(eol);
759         for (var i = 0; i < lines.length; i++) {
760                 lines[i] = lines[i].replace(/^\s+|\s+$/g, "");
761         }
762         return lines.join(eol);
763 }
764
765 </script>
766
767 </scriptlet>