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