Finding and sorting by diacriticals

Cubist at aol.com Cubist at aol.com
Wed Mar 5 06:22:01 EST 2003


   I wrote a HyperTalk handler to perform an offset function that's sensitive 
to both diacriticals and capitalization:

function IntlOffset Str1,Str2
  put offset (Str1,Str2) into Fred
  if Fred <> 0 then
    put the length of Str1 into LenS1
    put numToChar (8) into NullChar
    repeat until Fred = 0
      put char Fred to (Fred + LenS1 - 1) of Str2 into Str3
      if not ((Str1 < Str3) or (Str1 > Str3)) then exit repeat
      put NullChar into char Fred of Str2
      put offset (Str1,Str2) into Fred
    end repeat
  end if
  return Fred
end IntlOffset

   I gave this puppy some rudimentary testing in MetaCard 2.4.1 running under 
MacOS 8.6, and it seems to work fine. The trick is that second line inside 
the repeat loop: "if not ((Str1 < Str3) or (Str1 > Str3)) then exit repeat". 
In HyperTalk (and, apparently, in Transcript as well?), it is quite possible 
for two strings to return 'true' to *both* "StringA < StringB" *and* "StringA 
= StringB". This is because the poor engine is confused about capitalization 
and diacriticals. However, if StringA is neither greater than nor less than 
StringB, you can be confident that the two strings really and truly are equal!

   As for sorting, I've got another handler (a garden-variety Shell sort) 
which should theoretically do the job. While it works just fine in HyperCard, 
note that I have *not* tested it in MetaCard! This shouldn't be a serious 
problem -- even if MC barfs on this specific handler, the underlying logic 
ought to be clear enough that you can easily implement this algorithm in 
Transcript. 

function LSort TheList
  put (1 + the number of lines in TheList) div 2 into Pivott
  put "" into S1
  put line Pivott of TheList into S2
  put "" into S3
  delete line Pivott of TheList
  repeat with K1 = 1 to the number of lines in TheList
    put line 1 of TheList into ThisUnit
    delete line 1 of TheList
    if ThisUnit < S2 then -- this is the sort/test!
      put ThisUnit into line (1 + the number of lines in S1) of S1
    else
      put ThisUnit into line (1 + the number of lines in S3) of S3
    end if
  end repeat
  if S1   "" then
    put LSort (S1) & return before S2
  end if
  if S3   "" then
    put return & LSort (S3) after S2
  end if
  return S2
end LSort

   Hope this helps...



More information about the use-livecode mailing list