1. ----------------------------------------
  2. -- concatenates 2 text-member into new text member (preserving format and hyperlinks)
  3. ----------------------------------------
  4. on concatenateTextMembers (newMem, m1, m2)
  5.   newMem.rtf = concatenateRTF (m1.rtf, m2.rtf)
  6.   hl = m1.hyperlinks
  7.   repeat with h in hl
  8.     newMem.char[h[1]..h[2]].hyperlink = m1.char[h[1]..h[2]].hyperlink
  9.   end repeat
  10.   tOffset = m1.text.length + 1 -- because of automatic linebreak after m1
  11.   hl = m2.hyperlinks
  12.   repeat with h in hl
  13.     newMem.char[tOffset+h[1]..tOffset+h[2]].hyperlink = m2.char[h[1]..h[2]].hyperlink
  14.   end repeat
  15. end
  16.  
  17. ----------------------------------------
  18. -- concatenates 2 rtf-docs (given as rtf-text)
  19. ----------------------------------------
  20. on concatenateRTF (r1, r2)
  21.  
  22.   od = the itemdelimiter
  23.   the itemdelimiter=";"
  24.  
  25.   -- delete ending "}" of doc 1
  26.   delete the last char of r1
  27.  
  28.   -- delete rtf-header of doc 2
  29.   delete char 1 to 18 of r2
  30.  
  31.   -- separate header and body (separator: first occurence of \pard)
  32.   pos = offset("\pard",r1)
  33.   h1 = stripCRLF(r1.char[1..pos]) -- header 1
  34.   b1 = r1.char[pos+1..r1.length] -- body 1
  35.  
  36.   pos = offset("\pard",r2)
  37.   h2 = stripCRLF(r2.char[1..pos]) -- header 2
  38.   b2 = r2.char[pos+1..r2.length] -- body 2
  39.  
  40.  
  41.   -- COLOR-TABLE STUFF
  42.  
  43.   -- extract color-table of doc 1
  44.   ac1=offset("{\colortbl", h1) + 10
  45.   bc1=offset("}", h1.char[ac1+1..h1.length])
  46.   ct1=h1.char[ac1..ac1+bc1-2]
  47.   cnt1 = ct1.item.count
  48.  
  49.   -- extract color-table of doc 2
  50.   ac2=offset("{\colortbl", h2) + 10
  51.   bc2=offset("}", h2.char[ac2+1..h2.length])
  52.   ct2=h2.char[ac2..ac2+b2-2]
  53.   cnt2 = ct2.item.count
  54.  
  55.   -- create new complete color-table in h1
  56.   h1 = h1.char[1..ac1+bc1-2] & ";" & ct2 & h1.char[ac1+bc1-1..h1.length]
  57.  
  58.   -- delete old color-table in h2
  59.   delete char ac2 to ac2+bc2-2 of h2
  60.  
  61.   -- replace color-table-references in doc 2 with new indexes
  62.   repeat with i = cnt2 down to 1
  63.     b2 = str_replace_esc("\cf"&i, "\cf"&(i+cnt1), b2, "\")
  64.   end repeat
  65.  
  66.  
  67.   -- FONT-TABLE STUFF
  68.  
  69.   -- extract font-table of h1
  70.   af1=offset("{\fonttbl", h1) + 10
  71.   bf1=offset("}}", h1.char[af1+1..h1.length])
  72.   ft1=h1.char[af1..af1+bf1-2]
  73.   ar1=explode(";}{", ft1)
  74.  
  75.   -- extract font-table of h2
  76.   af2=offset("{\fonttbl", h2) + 10
  77.   bf2=offset("}}", h2.char[af2+1..h2.length])
  78.   ft2=h2.char[af2..af2+bf2-2]
  79.   ar2=explode(";}{", ft2)
  80.  
  81.   -- create new complete font-table in h1
  82.   fc1=count(ar1)
  83.   fc2=count(ar2)
  84.   repeat with i = 1 to fc2
  85.     f=ar2[i]
  86.     delete char 1 to 2 of f  
  87.     neu="\f"&(fc1+i-1)&f.char[offset("\",f)..f.length]
  88.     ar1.add(neu)
  89.   end repeat
  90.   h1 = h1.char[1..af1+bf1-2] & ";" & implode(";}{", ar1) & h1.char[af1+bf1-1..h1.length] -- ???
  91.  
  92.   -- delete old font-table in h2
  93.   delete char af2 to af2+bf2-2 of h2
  94.  
  95.   -- replace font-table-references in doc 2 with new indexes
  96.   repeat with i = fc2 down to 1
  97.     b2 = str_replace_esc("\f"&i, "\f"&(fc1+i), b2, "\")
  98.   end repeat
  99.  
  100.   -- concatenate
  101.   ret = h1 & b1 & h2 & b2
  102.  
  103.   return ret
  104. end
  105.  
  106. ----------------------------------------
  107. -- UTILITIES
  108. ----------------------------------------
  109.  
  110. ----------------------------------------
  111. -- strip CRLF, if necessary
  112. ----------------------------------------
  113. on stripCRLF aString
  114.   return str_replace(numtochar(13)&numtochar(10),"",aString)
  115. end
  116.  
  117. ----------------------------------------
  118. --replace in string, only if stringToFind is not escaped, i.e. uneven number
  119. ----------------------------------------
  120. on str_replace_esc (stringToFind, stringToInsert, input, esc)
  121.   output = ""
  122.   findLen = stringToFind.length - 1
  123.   repeat while true
  124.     currOffset = offset(stringToFind, input)
  125.     if currOffset=0 then exit repeat
  126.    
  127.     put input.char [1..currOffset] after output
  128.     delete the last char of output
  129.    
  130.     j=1
  131.     repeat while (input.char[currOffset-j]=esc) -- "\"
  132.       j=j+1
  133.     end repeat
  134.    
  135.     if j mod 2 = 1 then
  136.       put stringToInsert after output
  137.     else
  138.       put stringToFind after output
  139.     end if
  140.    
  141.     delete input.char [1.. (currOffset + findLen)]
  142.   end repeat
  143.   put input after output
  144.  
  145.   return output
  146. end
  147.  
  148. ----------------------------------------
  149. --
  150. ----------------------------------------
  151. on explode (delim, str)
  152.   l=[]
  153.   if voidP(str) then return []
  154.   dl=length(delim)
  155.   repeat while true
  156.     pos=offset(delim,str)
  157.     if pos=0 then exit repeat
  158.     s=str.char[1..pos]
  159.     delete the last char of s
  160.     l.add(s)
  161.     str=str.char[pos+dl..length(str)]
  162.   end repeat
  163.   if pos=0 then pos=1-dl
  164.   l.add(str.char[pos+dl..length(str)])
  165.   return l
  166. end
  167.  
  168. ----------------------------------------
  169. --
  170. ----------------------------------------
  171. on implode (delim, l)
  172.   str=""
  173.   repeat with i=1 to l.count
  174.     put l[i]&delim after str
  175.   end repeat
  176.   return str.char[1..(str.length-delim.length)]
  177. end
  178.  
  179. ----------------------------------------
  180. -- replace in string
  181. ----------------------------------------
  182. on str_replace stringToFind, stringToInsert, input
  183.   output = ""
  184.   findLen = stringToFind.length - 1
  185.   repeat while true
  186.     currOffset = offset(stringToFind, input)
  187.     if currOffset=0 then exit repeat
  188.     put input.char [1..currOffset] after output
  189.     delete the last char of output
  190.     put stringToInsert after output
  191.     delete input.char [1.. (currOffset + findLen)]
  192.   end repeat
  193.   put input after output
  194.   return output
  195. end
  196.  
  197.  
[raw code]