rtf2html3.bas
上传用户:bcdefg2008
上传日期:2013-02-28
资源大小:144k
文件大小:35k
源码类别:

Email服务器

开发平台:

Visual Basic

  1. Attribute VB_Name = "rtf2html"
  2. Option Explicit
  3. Private strCurPhrase As String
  4. Private strHTML As String
  5. Private Codes() As String
  6. Private NextCodes() As String
  7. Private CodesBeg() As String         'beginning codes
  8. Private NextCodesBeg() As String     'beginning codes for next text
  9. Private CodesTmp() As String         'temp stack for copying
  10. Private CodesTmpBeg() As String      'temp stack for copying beg
  11. Public strCR As String           'string to use for CRs - blank if +CR not chosen in options
  12. Private strBeforeText As String
  13. Private strBeforeText2 As String
  14. Private strBeforeText3 As String
  15. Private gPlain As Boolean            'true if all codes shouls be popped before next text
  16. Private strColorTable() As String    'table of colors
  17. Private lColors As Long              '# of colors
  18. Private strFontTable() As String     'table of fonts
  19. Private lFonts As Long               '# of fonts
  20. Private strEOL As String             'string to include before <br>
  21. Private lSkipWords As Long           'number od words to skip from current
  22. Private gBOL As Boolean              'a <br> was inserted but no non-whitespace text has been inserted
  23. Private strFont As String
  24. Private strTable As String
  25. Private strFontColor As String     'current font color for setting up fontstring
  26. Private strFontSize As String      'current font size for setting up fontstring
  27. Private lFontSize As Long
  28. Function ClearCodes()
  29.     ReDim Codes(0)
  30.     ReDim NextCodes(0)
  31.     ReDim CodesBeg(0)
  32.     ReDim NextCodesBeg(0)
  33. End Function
  34. Function ClearFont()
  35.     strFont = ""
  36.     strTable = ""
  37.     strFontColor = ""
  38.     strFontSize = ""
  39.     lFontSize = 0
  40. End Function
  41. Function Codes2NextTill(strCode As String)
  42.     
  43.     Dim l As Long
  44.     l = UBound(Codes)
  45.     While Codes(l) <> strCode And l >= 0
  46.         l = l - 1
  47.     Wend
  48.     CodesBeg(l) = ""
  49.     l = l + 1
  50.     While l <= UBound(Codes)
  51.         PushNext (Codes(l))
  52.         PushNextBeg (CodesBeg(l))
  53.         CodesBeg(l) = ""
  54.         l = l + 1
  55.     Wend
  56. End Function
  57. Function GetColorTable(strSecTmp As String, strColorTable() As String)
  58.     'get color table data and fill in strColorTable array
  59.     Dim lColors As Long
  60.     Dim lBOS As Long
  61.     Dim lEOS As Long
  62.     Dim strTmp As String
  63.     
  64.     lBOS = InStr(strSecTmp, "colortbl")
  65.     ReDim strColorTable(0)
  66.     lColors = 1
  67.     If lBOS <> 0 Then
  68.         lEOS = InStr(lBOS, strSecTmp, ";}")
  69.         If lEOS <> 0 Then
  70.             lBOS = InStr(lBOS, strSecTmp, "red")
  71.             While ((lBOS <= lEOS) And (lBOS <> 0))
  72.                 ReDim Preserve strColorTable(lColors)
  73.                 strTmp = Trim(Hex(Mid(strSecTmp, lBOS + 4, 1) & IIf(IsNumeric(Mid(strSecTmp, lBOS + 5, 1)), Mid(strSecTmp, lBOS + 5, 1), "") & IIf(IsNumeric(Mid(strSecTmp, lBOS + 6, 1)), Mid(strSecTmp, lBOS + 6, 1), "")))
  74.                 If Len(strTmp) = 1 Then strTmp = "0" & strTmp
  75.                 strColorTable(lColors) = strColorTable(lColors) & strTmp
  76.                 lBOS = InStr(lBOS, strSecTmp, "green")
  77.                 strTmp = Trim(Hex(Mid(strSecTmp, lBOS + 6, 1) & IIf(IsNumeric(Mid(strSecTmp, lBOS + 7, 1)), Mid(strSecTmp, lBOS + 7, 1), "") & IIf(IsNumeric(Mid(strSecTmp, lBOS + 8, 1)), Mid(strSecTmp, lBOS + 8, 1), "")))
  78.                 If Len(strTmp) = 1 Then strTmp = "0" & strTmp
  79.                 strColorTable(lColors) = strColorTable(lColors) & strTmp
  80.                 lBOS = InStr(lBOS, strSecTmp, "blue")
  81.                 strTmp = Trim(Hex(Mid(strSecTmp, lBOS + 5, 1) & IIf(IsNumeric(Mid(strSecTmp, lBOS + 6, 1)), Mid(strSecTmp, lBOS + 6, 1), "") & IIf(IsNumeric(Mid(strSecTmp, lBOS + 7, 1)), Mid(strSecTmp, lBOS + 7, 1), "")))
  82.                 If Len(strTmp) = 1 Then strTmp = "0" & strTmp
  83.                 strColorTable(lColors) = strColorTable(lColors) & strTmp
  84.                 lBOS = InStr(lBOS, strSecTmp, "red")
  85.                 lColors = lColors + 1
  86.             Wend
  87.         End If
  88.     End If
  89. End Function
  90. Function GetFontTable(strSecTmp As String, strFontTable() As String)
  91.     'get font table data and fill in strFontTable array
  92.     Dim lFonts As Long
  93.     Dim lBOS As Long
  94.     Dim lEOS As Long
  95.     Dim strTmp As String
  96.     
  97.     lBOS = InStr(strSecTmp, "fonttbl")
  98.     ReDim strFontTable(0)
  99.     lFonts = 0
  100.     If lBOS <> 0 Then
  101.         lEOS = InStr(lBOS, strSecTmp, ";}}")
  102.         If lEOS <> 0 Then
  103.             lBOS = InStr(lBOS, strSecTmp, "f0")
  104.             While ((lBOS <= lEOS) And (lBOS <> 0))
  105.                 ReDim Preserve strFontTable(lFonts)
  106.                 While ((Mid(strSecTmp, lBOS, 1) <> " ") And (lBOS <= lEOS))
  107.                     lBOS = lBOS + 1
  108.                 Wend
  109.                 lBOS = lBOS + 1
  110.                 strTmp = Mid(strSecTmp, lBOS, InStr(lBOS, strSecTmp, ";") - lBOS)
  111.                 strFontTable(lFonts) = strFontTable(lFonts) & strTmp
  112.                 lBOS = InStr(lBOS, strSecTmp, "f" & (lFonts + 1))
  113.                 lFonts = lFonts + 1
  114.             Wend
  115.         End If
  116.     End If
  117. End Function
  118. Function InNext(strTmp) As Boolean
  119.     Dim gTmp As Boolean
  120.     Dim l As Long
  121.     
  122.     l = 1
  123.     gTmp = False
  124.     While l <= UBound(NextCodes) And Not gTmp
  125.         If NextCodes(l) = strTmp Then gTmp = True
  126.         l = l + 1
  127.     Wend
  128.     InNext = gTmp
  129. End Function
  130. Function InCodes(strTmp) As Boolean
  131.     Dim gTmp As Boolean
  132.     Dim l As Long
  133.     
  134.     l = 1
  135.     gTmp = False
  136.     While l <= UBound(Codes) And Not gTmp
  137.         If Codes(l) = strTmp And Len(CodesBeg(l)) > 0 Then gTmp = True
  138.         l = l + 1
  139.     Wend
  140.     InCodes = gTmp
  141. End Function
  142. Function NabNextLine(strRTF As String) As String
  143.     Dim l As Long
  144.     
  145.     l = InStr(strRTF, vbCrLf)
  146.     If l = 0 Then l = Len(strRTF)
  147.     NabNextLine = TrimAll(Left(strRTF, l))
  148.     If l = Len(strRTF) Then
  149.         strRTF = ""
  150.     Else
  151.         strRTF = TrimAll(Mid(strRTF, l))
  152.     End If
  153. End Function
  154. Function NabNextWord(strLine As String) As String
  155.     Dim l As Long
  156.     Dim lvl As Integer
  157.     Dim gEndofWord As Boolean
  158.     Dim gInCommand As Boolean    'current word is command instead of plain word
  159.     
  160.     gInCommand = False
  161.     l = 0
  162.     lvl = 0
  163.     'strLine = TrimifCmd(strLine)
  164.     If Left(strLine, 1) = "}" Then
  165.         strLine = Mid(strLine, 2)
  166.         NabNextWord = "}"
  167.         GoTo finally
  168.     End If
  169.     While Not gEndofWord
  170.         l = l + 1
  171.         If l >= Len(strLine) Then
  172.             If l = Len(strLine) Then l = l + 1
  173.             gEndofWord = True
  174.         ElseIf InStr("{}", Mid(strLine, l, 1)) Then
  175.             If l = 1 And Mid(strLine, l, 1) = "" Then gInCommand = True
  176.             If Mid(strLine, l + 1, 1) <> "" And l > 1 And lvl = 0 Then
  177.                 gEndofWord = True
  178.             End If
  179.         ElseIf Mid(strLine, l, 1) = " " And lvl = 0 And gInCommand Then
  180.             gEndofWord = True
  181.         End If
  182.     Wend
  183.     
  184.     If l = 0 Then l = Len(strLine)
  185.     NabNextWord = Left(strLine, l - 1)
  186.     While Len(NabNextWord) > 0 And InStr("{}", Right(NabNextWord, 1))
  187.         NabNextWord = Left(NabNextWord, Len(NabNextWord) - 1)
  188.     Wend
  189.     While Len(NabNextWord) > 0 And InStr("{}", Left(NabNextWord, 1))
  190.         NabNextWord = Right(NabNextWord, Len(NabNextWord) - 1)
  191.     Wend
  192.     strLine = Mid(strLine, l)
  193.     If Left(strLine, 1) = " " Then strLine = Mid(strLine, 2)
  194. finally:
  195. End Function
  196. Function NabSection(strRTF As String, lPos As Long) As String
  197.     'grab section surrounding lPos, strip section out of strRTF and return it
  198.     Dim lBOS As Long         'beginning of section
  199.     Dim lEOS As Long         'ending of section
  200.     Dim strChar As String
  201.     Dim lLev As Long         'level of brackets/parens
  202.     Dim lRTFLen As Long
  203.     
  204.     lRTFLen = Len(strRTF)
  205.     
  206.     lBOS = lPos
  207.     strChar = Mid(strRTF, lBOS, 1)
  208.     lLev = 1
  209.     While lLev > 0
  210.         lBOS = lBOS - 1
  211.         If lBOS <= 0 Then
  212.             lLev = lLev - 1
  213.         Else
  214.             strChar = Mid(strRTF, lBOS, 1)
  215.             If strChar = "}" Then
  216.                 lLev = lLev + 1
  217.             ElseIf strChar = "{" Then
  218.                 lLev = lLev - 1
  219.             End If
  220.         End If
  221.     Wend
  222.     lBOS = lBOS - 1
  223.     If lBOS < 1 Then lBOS = 1
  224.     
  225.     lEOS = lPos
  226.     strChar = Mid(strRTF, lEOS, 1)
  227.     lLev = 1
  228.     While lLev > 0
  229.         lEOS = lEOS + 1
  230.         If lEOS >= lRTFLen Then
  231.             lLev = lLev - 1
  232.         Else
  233.             strChar = Mid(strRTF, lEOS, 1)
  234.             If strChar = "{" Then
  235.                 lLev = lLev + 1
  236.             ElseIf strChar = "}" Then
  237.                 lLev = lLev - 1
  238.             End If
  239.         End If
  240.     Wend
  241.     lEOS = lEOS + 1
  242.     If lEOS > lRTFLen Then lEOS = lRTFLen
  243.     NabSection = Mid(strRTF, lBOS + 1, lEOS - lBOS - 1)
  244.     strRTF = Mid(strRTF, 1, lBOS) & Mid(strRTF, lEOS)
  245.     strRTF = rtf2html_replace(strRTF, vbCrLf & vbCrLf, vbCrLf)
  246. End Function
  247. Function Next2Codes()
  248.     'move codes from pending ("next") stack to current stack
  249.     Dim lNumCodes As Long
  250.     Dim l As Long
  251.     
  252.     If UBound(NextCodes) > 0 Then
  253.         lNumCodes = UBound(Codes)
  254.         ReDim Preserve Codes(lNumCodes + UBound(NextCodes))
  255.         ReDim Preserve CodesBeg(lNumCodes + UBound(NextCodes))
  256.         For l = 1 To UBound(NextCodes)
  257.             Codes(lNumCodes + l) = NextCodes(l)
  258.             CodesBeg(lNumCodes + l) = NextCodesBeg(l)
  259.         Next l
  260.         ReDim NextCodes(0)
  261.         ReDim NextCodesBeg(0)
  262.     End If
  263. End Function
  264. Function Codes2Next()
  265.     'move codes from "current" stack to pending ("next") stack
  266.     Dim lNumCodes As Long
  267.     Dim l As Long
  268.     
  269.     If UBound(Codes) > 0 Then
  270.         lNumCodes = UBound(NextCodes)
  271.         ReDim Preserve NextCodes(lNumCodes + UBound(Codes))
  272.         ReDim Preserve NextCodesBeg(lNumCodes + UBound(Codes))
  273.         For l = 1 To UBound(Codes)
  274.             NextCodes(lNumCodes + l) = Codes(l)
  275.             NextCodesBeg(lNumCodes + l) = CodesBeg(l)
  276.         Next l
  277.         ReDim Codes(0)
  278.         ReDim CodesBeg(0)
  279.     End If
  280. End Function
  281. Function ParseFont(strColor As String, strSize As String) As String
  282.     Dim strTmpFont As String
  283.     
  284.     strTmpFont = "<font"
  285.     If strColor <> "" Then
  286.        strTmpFont = strTmpFont & " color=""" & strColor & """"
  287.     End If
  288.     If strSize <> "" And strSize <> "2" Then
  289.         strTmpFont = strTmpFont & " size=" & strSize
  290.     End If
  291.     strTmpFont = strTmpFont & ">"
  292.     ParseFont = strTmpFont
  293. End Function
  294. Function PopCode() As String
  295.     If UBound(Codes) > 0 Then
  296.         PopCode = Codes(UBound(Codes))
  297.         ReDim Preserve Codes(UBound(Codes) - 1)
  298.     End If
  299. End Function
  300. Function GetAllCodes() As String
  301.     Dim strTmp As String
  302.     Dim l As Long
  303.     
  304.     strTmp = ""
  305.     If UBound(Codes) > 0 Then
  306.         For l = UBound(Codes) To 1 Step -1
  307.             strTmp = strTmp & Codes(l)
  308.         Next l
  309.     End If
  310.     GetAllCodes = strTmp
  311. End Function
  312. Function GetAllNextCodes() As String
  313.     Dim strTmp As String
  314.     Dim l As Long
  315.     
  316.     strTmp = ""
  317.     If UBound(NextCodes) > 0 Then
  318.         For l = 1 To UBound(NextCodes)
  319.             strTmp = strTmp & NextCodes(l)
  320.         Next l
  321.     End If
  322.     GetAllNextCodes = strTmp
  323. End Function
  324. Function GetAllCodesBeg() As String
  325.     Dim strTmp As String
  326.     Dim l As Long
  327.     
  328.     strTmp = ""
  329.     If UBound(CodesBeg) > 0 Then
  330.         For l = 1 To UBound(CodesBeg)
  331.             strTmp = strTmp & CodesBeg(l)
  332.         Next l
  333.     End If
  334.     GetAllCodesBeg = strTmp
  335. End Function
  336. Function GetAllNextCodesBeg() As String
  337.     Dim strTmp As String
  338.     Dim l As Long
  339.     
  340.     strTmp = ""
  341.     If UBound(NextCodesBeg) > 0 Then
  342.         For l = 1 To UBound(NextCodesBeg)
  343.             strTmp = strTmp & NextCodesBeg(l)
  344.         Next l
  345.     End If
  346.     GetAllNextCodesBeg = strTmp
  347. End Function
  348. Function PopCodeBeg() As String
  349.     If UBound(CodesBeg) > 0 Then
  350.         PopCodeBeg = CodesBeg(UBound(CodesBeg))
  351.         ReDim Preserve CodesBeg(UBound(CodesBeg) - 1)
  352.     End If
  353. End Function
  354. Function PopTmp() As String
  355.     If UBound(CodesTmp) > 0 Then
  356.         PopTmp = CodesTmp(UBound(CodesTmp))
  357.         ReDim Preserve CodesTmp(UBound(CodesTmp) - 1)
  358.     End If
  359. End Function
  360. Function PopTmpBeg() As String
  361.     If UBound(CodesTmp) > 0 Then
  362.         PopTmpBeg = CodesTmpBeg(UBound(CodesTmpBeg))
  363.         ReDim Preserve CodesTmpBeg(UBound(CodesTmpBeg) - 1)
  364.     End If
  365. End Function
  366. Function PopNext() As String
  367.     If UBound(NextCodes) > 0 Then
  368.         PopNext = NextCodes(UBound(NextCodes))
  369.         ReDim Preserve NextCodes(UBound(NextCodes) - 1)
  370.     End If
  371. End Function
  372. Function PopNextBeg() As String
  373.     If UBound(NextCodesBeg) > 0 Then
  374.         PopNextBeg = NextCodesBeg(UBound(NextCodesBeg))
  375.         ReDim Preserve NextCodesBeg(UBound(NextCodesBeg) - 1)
  376.     End If
  377. End Function
  378. Function ProcessWord(strWord As String)
  379.     
  380.     
  381.     Dim l As Long
  382.     
  383.     
  384.     Dim strTableAlign As String    'current table alignment for setting up tablestring
  385.     Dim strTableWidth As String    'current table width for setting up tablestring
  386.     
  387.     If lSkipWords > 0 Then
  388.         lSkipWords = lSkipWords - 1
  389.         Exit Function
  390.     End If
  391.     If Left(strWord, 1) = "" Or Left(strWord, 1) = "{" Or Left(strWord, 1) = "}" Then
  392.         Select Case Left(strWord, 2)
  393.         Case "}"
  394.             For l = 1 To UBound(CodesBeg)
  395.                 CodesBeg(l) = ""
  396.             Next l
  397.             ClearFont
  398.         Case "b"    'bold
  399.             If strWord = "b" Then
  400.                 If Codes(UBound(Codes)) <> "</b>" Or (Codes(UBound(Codes)) = "</b>" And CodesBeg(UBound(Codes)) = "") Then
  401.                     PushNext ("</b>")
  402.                     PushNextBeg ("<b>")
  403.                 End If
  404.             ElseIf strWord = "bullet" Then
  405.             ElseIf strWord = "b0" Then    'bold off
  406.                 If InCodes("</b>") Then
  407.                     Codes2NextTill ("</b>")
  408.                 ElseIf InNext("</b>") Then
  409.                     RemoveFromNext ("</b>")
  410.                 End If
  411.             End If
  412.         Case "c"
  413.             If strWord = "cf0" Then    'color font off
  414.                 If InCodes("</font>") Then
  415.                     Codes2NextTill ("</font>")
  416.                 ElseIf InNext("</font>") Then
  417.                     RemoveFromNext ("</font>")
  418.                 End If
  419.             ElseIf Left(strWord, 3) = "cf" And IsNumeric(Mid(strWord, 4)) Then  'color font
  420.                 'get color code
  421.                 l = Val(Mid(strWord, 4))
  422.                 If l <= UBound(strColorTable) And l > 0 Then
  423.                     strFontColor = "#" & strColorTable(l)
  424.                 End If
  425.                 
  426.                 'insert color
  427.                 If strFontColor <> "#" Then
  428.                     strFont = ParseFont(strFontColor, strFontSize)
  429.                     If InNext("</font>") Then
  430.                         ReplaceInNextBeg "</font>", strFont
  431.                     ElseIf InCodes("</font>") Then
  432.                         PushNext ("</font>")
  433.                         PushNextBeg (strFont)
  434.                         Codes2NextTill "</font>"
  435.                     Else
  436.                         PushNext ("</font>")
  437.                         PushNextBeg (strFont)
  438.                     End If
  439.                 End If
  440.             End If
  441.         Case "f"
  442.             If Left(strWord, 3) = "fs" And IsNumeric(Mid(strWord, 4)) Then  'font size
  443.                 l = Val(Mid(strWord, 4))
  444.                 lFontSize = Int((l / 6) - 0)    'calc to convert RTF to HTML sizes
  445.                 If lFontSize > 8 Then lFontSize = 8
  446.                 If lFontSize < 1 Then lFontSize = 1
  447.                 strFontSize = Trim(lFontSize)
  448.                 'insert size
  449.                 If strFontSize <> "2" And strFontSize <> "" Then
  450.                     strFont = ParseFont(strFontColor, strFontSize)
  451.                     If InNext("</font>") Then
  452.                         ReplaceInNextBeg "</font>", strFont
  453.                     ElseIf InCodes("</font>") Then
  454.                         PushNext ("</font>")
  455.                         PushNextBeg (strFont)
  456.                         Codes2NextTill "</font>"
  457.                     Else
  458.                         PushNext ("</font>")
  459.                         PushNextBeg (strFont)
  460.                     End If
  461.                 End If
  462.             End If
  463.         Case "i"
  464.             If strWord = "i" Then 'italics
  465.                 If Codes(UBound(Codes)) <> "</i>" Or (Codes(UBound(Codes)) = "</i>" And CodesBeg(UBound(Codes)) = "") Then
  466.                     PushNext ("</i>")
  467.                     PushNextBeg ("<i>")
  468.                 End If
  469.             ElseIf strWord = "i0" Then 'italics off
  470.                 If InCodes("</i>") Then
  471.                     Codes2NextTill ("</i>")
  472.                 ElseIf InNext("</i>") Then
  473.                     RemoveFromNext ("</i>")
  474.                 End If
  475.             End If
  476.         Case "l"
  477.             'If strWord = "listname" Then
  478.             '    lSkipWords = 1
  479.             'End If
  480.         Case "p"
  481.             If strWord = "par" Then
  482.                 strBeforeText2 = strBeforeText2 & strEOL & "<br>" & strCR
  483.                 gBOL = True
  484.                 'If Len(strBOL) > 0 Then
  485.                 '    PushNext ("</li>")
  486.                 '    PushNextBeg ("<li>")
  487.                 'End If
  488.             ElseIf strWord = "pard" Then
  489.                 For l = 1 To UBound(CodesBeg)
  490.                     CodesBeg(l) = ""
  491.                 Next l
  492.                 ClearFont
  493.             ElseIf strWord = "plain" Then
  494.                 For l = 1 To UBound(CodesBeg)
  495.                     CodesBeg(l) = ""
  496.                 Next l
  497.                 ClearFont
  498.             ElseIf strWord = "pnlvlblt" Then 'bulleted list
  499.                 'If Codes(UBound(Codes)) = "</u>" Then
  500.                 '    strTmp = PopCode
  501.                 '    strTmp = PopCodeBeg
  502.                 'End If
  503.                 'PushNext ("</ul>")
  504.                 'PushNextBeg ("<ul>")
  505.                 'strBOS = "<UL>"
  506.                 'strBOL = "<li>"
  507.                 'strEOL = "</li>"
  508.                 'strEOP = "</UL>"
  509.             ElseIf strWord = "pntxta" Then 'numbered list?
  510.                 lSkipWords = 1
  511.             ElseIf strWord = "pntxtb" Then 'numbered list?
  512.                 lSkipWords = 1
  513.             End If
  514.         Case "q"
  515.             If strWord = "qc" Then    'centered
  516.                 strTableAlign = "center"
  517.                 strTableWidth = "100%"
  518.                 If InNext("</td></tr></table>") Then
  519.                     '?
  520.                 Else
  521.                     strTable = "<table width=" & strTableWidth & "><tr><td align=""" & strTableAlign & """>"
  522.                 End If
  523.                 If InNext("</td></tr></table>") Then
  524.                     ReplaceInNextBeg "</td></tr></table>", strTable
  525.                 ElseIf InCodes("</td></tr></table>") Then
  526.                     PushNext ("</td></tr></table>")
  527.                     PushNextBeg (strTable)
  528.                     Codes2NextTill "</td></tr></table>"
  529.                 Else
  530.                     PushNext ("</td></tr></table>")
  531.                     PushNextBeg (strTable)
  532.                 End If
  533.             ElseIf strWord = "qr" Then    'right justified
  534.                 strTableAlign = "right"
  535.                 strTableWidth = "100%"
  536.                 If InNext("</td></tr></table>") Then
  537.                     '?
  538.                 Else
  539.                     strTable = "<table width=" & strTableWidth & "><tr><td align=""" & strTableAlign & """>"
  540.                 End If
  541.                 If InNext("</td></tr></table>") Then
  542.                     ReplaceInNextBeg "</td></tr></table>", strTable
  543.                 ElseIf InCodes("</td></tr></table>") Then
  544.                     PushNext ("</td></tr></table>")
  545.                     PushNextBeg (strTable)
  546.                     Codes2NextTill "</td></tr></table>"
  547.                 Else
  548.                     PushNext ("</td></tr></table>")
  549.                     PushNextBeg (strTable)
  550.                 End If
  551.             End If
  552.         Case "s"
  553.             'If strWord = "snext0" Then    'style
  554.             '    lSkipWords = 1
  555.             'End If
  556.         Case "u"
  557.             If strWord = "ul" Then    'underline
  558.                 If Codes(UBound(Codes)) <> "</u>" Or (Codes(UBound(Codes)) = "</u>" And CodesBeg(UBound(Codes)) = "") Then
  559.                     PushNext ("</u>")
  560.                     PushNextBeg ("<u>")
  561.                 End If
  562.             ElseIf strWord = "ulnone" Then    'stop underline
  563.                 If InCodes("</u>") Then
  564.                     Codes2NextTill ("</u>")
  565.                 ElseIf InNext("</u>") Then
  566.                     RemoveFromNext ("</u>")
  567.                 End If
  568.             End If
  569.         End Select
  570.     Else
  571.         If Len(strWord) > 0 Then
  572.             If Trim(strWord) = "" Then
  573.                 If gBOL Then strWord = rtf2html_replace(strWord, " ", "&nbsp;")
  574.                 strCurPhrase = strCurPhrase & strBeforeText3 & strWord
  575.             Else
  576.                 strBeforeText = strBeforeText & GetAllCodes
  577.                 Next2Codes
  578.                 strBeforeText3 = GetAllCodesBeg
  579.                 RemoveBlanks
  580.                 
  581.                 strCurPhrase = strCurPhrase & strBeforeText
  582.                 strBeforeText = ""
  583.                 strCurPhrase = strCurPhrase & strBeforeText2
  584.                 strBeforeText2 = ""
  585.                 strCurPhrase = strCurPhrase & strBeforeText3 & strWord
  586.                 strBeforeText3 = ""
  587.                 gBOL = False
  588.             End If
  589.         End If
  590.     End If
  591.     'MsgBox (strWord)
  592. End Function
  593. Function PushCode(strCode As String)
  594.     ReDim Preserve Codes(UBound(Codes) + 1)
  595.     Codes(UBound(Codes)) = strCode
  596. End Function
  597. Function PushTmp(strCode As String)
  598.     ReDim Preserve CodesTmp(UBound(CodesTmp) + 1)
  599.     CodesTmp(UBound(CodesTmp)) = strCode
  600. End Function
  601. Function PushTmpBeg(strCode As String)
  602.     ReDim Preserve CodesTmpBeg(UBound(CodesTmpBeg) + 1)
  603.     CodesTmpBeg(UBound(CodesTmpBeg)) = strCode
  604. End Function
  605. Function PushCodeBeg(strCode As String)
  606.     ReDim Preserve CodesBeg(UBound(CodesBeg) + 1)
  607.     CodesBeg(UBound(CodesBeg)) = strCode
  608. End Function
  609. Function PushNext(strCode As String)
  610.     If Len(strCode) > 0 Then
  611.         ReDim Preserve NextCodes(UBound(NextCodes) + 1)
  612.         NextCodes(UBound(NextCodes)) = strCode
  613.     End If
  614. End Function
  615. Function PushNextBeg(strCode As String)
  616.     ReDim Preserve NextCodesBeg(UBound(NextCodesBeg) + 1)
  617.     NextCodesBeg(UBound(NextCodesBeg)) = strCode
  618. End Function
  619. Function RemoveBlanks()
  620.     Dim l As Long
  621.     Dim lOffSet As Long
  622.     
  623.     l = 1
  624.     lOffSet = 0
  625.     While l <= UBound(CodesBeg) And l + lOffSet <= UBound(CodesBeg)
  626.         If CodesBeg(l) = "" Then
  627.             lOffSet = lOffSet + 1
  628.         Else
  629.             l = l + 1
  630.         End If
  631.         If l + lOffSet <= UBound(CodesBeg) Then
  632.             Codes(l) = Codes(l + lOffSet)
  633.             CodesBeg(l) = CodesBeg(l + lOffSet)
  634.         End If
  635.     Wend
  636.     If lOffSet > 0 Then
  637.         ReDim Preserve Codes(UBound(Codes) - lOffSet)
  638.         ReDim Preserve CodesBeg(UBound(CodesBeg) - lOffSet)
  639.     End If
  640. End Function
  641. Function RemoveFromNext(strRem As String)
  642.     Dim l As Long
  643.     Dim m As Long
  644.     
  645.     l = 1
  646.     While l < UBound(NextCodes)
  647.         If NextCodes(l) = strRem Then
  648.             For m = l To UBound(NextCodes) - 1
  649.                 NextCodes(m) = NextCodes(m + 1)
  650.                 NextCodesBeg(m) = NextCodesBeg(m + 1)
  651.             Next m
  652.             l = m
  653.         Else
  654.             l = l + 1
  655.         End If
  656.     Wend
  657.     ReDim Preserve NextCodes(UBound(NextCodes) - 1)
  658.     ReDim Preserve NextCodesBeg(UBound(NextCodesBeg) - 1)
  659. End Function
  660. Function rtf2html_replace(ByVal strIn As String, ByVal strRepl As String, ByVal strWith As String) As String
  661.     'replace all instances of strRepl in strIn with strWith
  662.     Dim I As Integer
  663.     
  664.     If ((Len(strRepl) = 0) Or (Len(strIn) = 0)) Then
  665.         rtf2html_replace = strIn
  666.         Exit Function
  667.     End If
  668.     I = InStr(strIn, strRepl)
  669.     While I <> 0
  670.         strIn = Left(strIn, I - 1) & strWith & Mid(strIn, I + Len(strRepl))
  671.         I = InStr(I + Len(strWith), strIn, strRepl)
  672.     Wend
  673.     rtf2html_replace = strIn
  674. End Function
  675. Function ReplaceInNextBeg(strCode As String, strWith As String)
  676.     Dim l As Long
  677.     
  678.     l = 1
  679.     While l <= UBound(NextCodes) And NextCodes(l) <> strCode
  680.         l = l + 1
  681.     Wend
  682.     If NextCodes(l) = strCode Then
  683.         NextCodesBeg(l) = strWith
  684.     End If
  685. End Function
  686. Function rtf2html(strRTF As String, Optional strOptions As String) As String
  687.     'Version 3.01b04
  688.     'Copyright Brady Hegberg 2000
  689.     '  I'm not licensing this software but I'd appreciate it if
  690.     '  you'd to consider it to be under an lgpl sort of license
  691.     
  692.     'More information can be found at
  693.     'http://www2.bitstream.net/~bradyh/downloads/rtf2htmlrm.html
  694.     
  695.     'Converts Rich Text encoded text to HTML format
  696.     'if you find some text that this function doesn't
  697.     'convert properly please email the text to
  698.     'bradyh@bitstream.net
  699.     
  700.     'Options:
  701.     '+H              add an HTML header and footer
  702.     '+G              add a generator Metatag
  703.     '+T="MyTitle"    add a title (only works if +H is used)
  704.     '+CR             add a carraige return after all <br>s
  705.     '+I              keep html codes intact
  706.     
  707.     Dim strHTML As String
  708.     Dim strRTFTmp As String
  709.     Dim lBOS As Long                 'beginning of section                'end of section
  710.    
  711.     
  712.     
  713.     
  714.     
  715.     
  716.     
  717.     
  718.     
  719.     Dim gHTML As Boolean             'true if html codes should be left intact
  720.     Dim strSecTmp As String          'temporary section buffer
  721.     Dim strWordTmp As String         'temporary word buffer
  722.     Dim strEndText As String         'ending text
  723.     
  724.     Dim strHtmlBody As String
  725.   
  726.     
  727.     ClearCodes
  728.     strHTML = ""
  729.     gPlain = False
  730.     gBOL = True
  731.     
  732.     'setup +CR option
  733.     If InStr(strOptions, "+CR") <> 0 Then strCR = vbCrLf Else strCR = ""
  734.     'setup +HTML option
  735.     If InStr(strOptions, "+I") <> 0 Then gHTML = True Else gHTML = False
  736.     strRTFTmp = TrimAll(strRTF)
  737.     If Left(strRTFTmp, 1) = "{" And Right(strRTFTmp, 1) = "}" Then strRTFTmp = Mid(strRTFTmp, 2, Len(strRTFTmp) - 2)
  738.     
  739.     'setup color table
  740.     lBOS = InStr(strRTFTmp, "colortbl")
  741.     If lBOS > 0 Then
  742.         strSecTmp = NabSection(strRTFTmp, lBOS)
  743.         GetColorTable strSecTmp, strColorTable()
  744.     End If
  745.     
  746.     'setup font table
  747.     lBOS = InStr(strRTFTmp, "fonttbl")
  748.     If lBOS > 0 Then
  749.         strSecTmp = NabSection(strRTFTmp, lBOS)
  750.         GetFontTable strSecTmp, strFontTable()
  751.     End If
  752.     
  753.     'setup stylesheets
  754.     lBOS = InStr(strRTFTmp, "stylesheet")
  755.     If lBOS > 0 Then
  756.         strSecTmp = NabSection(strRTFTmp, lBOS)
  757.         'ignore stylesheets for now
  758.     End If
  759.     
  760.     'setup info
  761.     lBOS = InStr(strRTFTmp, "info")
  762.     If lBOS > 0 Then
  763.         strSecTmp = NabSection(strRTFTmp, lBOS)
  764.         'ignore info for now
  765.     End If
  766.     
  767.     'list table
  768.     lBOS = InStr(strRTFTmp, "listtable")
  769.     If lBOS > 0 Then
  770.         strSecTmp = NabSection(strRTFTmp, lBOS)
  771.         'ignore info for now
  772.     End If
  773.     
  774.     'list override table
  775.     lBOS = InStr(strRTFTmp, "listoverridetable")
  776.     If lBOS > 0 Then
  777.         strSecTmp = NabSection(strRTFTmp, lBOS)
  778.         'ignore info for now
  779.     End If
  780.     While Len(strRTFTmp) > 0
  781.         strSecTmp = NabNextLine(strRTFTmp)
  782.         While Len(strSecTmp) > 0
  783.             strWordTmp = NabNextWord(strSecTmp)
  784.             If Len(strWordTmp) > 0 Then ProcessWord strWordTmp
  785.         Wend
  786.     Wend
  787.     
  788.     'get any remaining codes in stack
  789.     Next2Codes
  790.     strEndText = strEndText & GetAllCodes
  791.     strBeforeText2 = rtf2html_replace(strBeforeText2, "<br>", "")
  792.     strBeforeText2 = rtf2html_replace(strBeforeText2, vbCrLf, "")
  793.     strCurPhrase = strCurPhrase & strBeforeText & strBeforeText2 & strEndText
  794.     strBeforeText = ""
  795.     strBeforeText2 = ""
  796.     strBeforeText3 = ""
  797.     strHTML = strHTML & strCurPhrase
  798.     strCurPhrase = ""
  799.     
  800.     Dim strTitel As String
  801.     
  802.     If InStr(strOptions, "+T=") > 0 Then
  803.         strTitel = GetTitel(0, "+T=", strOptions)
  804.     End If
  805.     
  806.     If InStr(strOptions, "+H") > 0 Then
  807.         strHtmlBody = strHtmlBody + "<HTML>" + strCR
  808.         strHtmlBody = strHtmlBody + "<HEAD>" + strCR
  809.         strHtmlBody = strHtmlBody + "<TITLE>" + strTitel + "</TITLE>" + strCR
  810.         strHtmlBody = strHtmlBody + "</HEAD>" + strCR
  811.         strHtmlBody = strHtmlBody + "<BODY bgcolor=" + "white" + " text=" + "black" + ">" + strCR
  812.     
  813.         rtf2html = strHtmlBody + strHTML + "</BODY>" + strCR + "</HTML>"
  814.     Else
  815.         rtf2html = strHTML
  816.     End If
  817. End Function
  818. Public Function GetTitel(intPosition As Long, SearchStr As String, ByRef strarray As String) As String
  819.   Dim strTemp As String
  820.   Dim strValue As String
  821.   Dim Counter As Integer
  822.   Dim StartPosi As Integer
  823.   
  824.     On Error GoTo error
  825.     
  826.     StartPosi = InStr(LCase$(strarray), SearchStr) + Len(SearchStr)
  827.     Do
  828.         strValue = strValue + strTemp
  829.         strTemp = Mid$(strarray, StartPosi + Counter, 1)
  830.         Counter = Counter + 1
  831.     Loop Until strTemp = vbCrLf Or Counter = Len(strarray)
  832.     'Remove the ""
  833.     If Left$(strValue, 1) = Chr$(34) Then strValue = Right$(strValue, Len(strValue) - 1)
  834.     If Right$(strValue, 1) = Chr$(34) Then strValue = Left$(strValue, Len(strValue) - 1)
  835.     GetTitel = Replace(strValue, " ", "")
  836. Exit Function
  837. error:
  838.     GetTitel = ""
  839. End Function
  840. Function ShowCodes()
  841.     Dim strTmp As String
  842.     Dim l As Long
  843.     
  844.     strTmp = "Codes: "
  845.     For l = 1 To UBound(Codes)
  846.         strTmp = strTmp & Codes(l) & ", "
  847.     Next l
  848.     strTmp = strTmp & vbCrLf & "BegCodes: "
  849.     For l = 1 To UBound(CodesBeg)
  850.         strTmp = strTmp & CodesBeg(l) & ", "
  851.     Next l
  852.     strTmp = strTmp & vbCrLf & "NextCodes: "
  853.     For l = 1 To UBound(NextCodes)
  854.         strTmp = strTmp & NextCodes(l) & ", "
  855.     Next l
  856.     strTmp = strTmp & vbCrLf & "NextBegCodes: "
  857.     For l = 1 To UBound(NextCodesBeg)
  858.         strTmp = strTmp & NextCodesBeg(l) & ", "
  859.     Next l
  860.     MsgBox (strTmp)
  861. End Function
  862. Function TrimAll(ByVal strTmp As String) As String
  863.     Dim l As Long
  864.     
  865.     strTmp = Trim(strTmp)
  866.     l = Len(strTmp) + 1
  867.     While l <> Len(strTmp)
  868.         l = Len(strTmp)
  869.         If Right(strTmp, 1) = vbCrLf Then strTmp = Left(strTmp, Len(strTmp) - 1)
  870.         If Left(strTmp, 1) = vbCrLf Then strTmp = Right(strTmp, Len(strTmp) - 1)
  871.         If Right(strTmp, 1) = vbCr Then strTmp = Left(strTmp, Len(strTmp) - 1)
  872.         If Left(strTmp, 1) = vbCr Then strTmp = Right(strTmp, Len(strTmp) - 1)
  873.         If Right(strTmp, 1) = vbLf Then strTmp = Left(strTmp, Len(strTmp) - 1)
  874.         If Left(strTmp, 1) = vbLf Then strTmp = Right(strTmp, Len(strTmp) - 1)
  875.     Wend
  876.     TrimAll = strTmp
  877. End Function
  878. Function HTMLCode(strRTFCode As String) As String
  879.     'given rtf code return html code
  880.     Select Case strRTFCode
  881.     Case "00"
  882.         HTMLCode = "&nbsp;"
  883.     Case "a9"
  884.         HTMLCode = "&copy;"
  885.     Case "b4"
  886.         HTMLCode = "&acute;"
  887.     Case "ab"
  888.         HTMLCode = "&laquo;"
  889.     Case "bb"
  890.         HTMLCode = "&raquo;"
  891.     Case "a1"
  892.         HTMLCode = "&iexcl;"
  893.     Case "bf"
  894.         HTMLCode = "&iquest;"
  895.     Case "c0"
  896.         HTMLCode = "&Agrave;"
  897.     Case "e0"
  898.         HTMLCode = "&agrave;"
  899.     Case "c1"
  900.         HTMLCode = "&Aacute;"
  901.     Case "e1"
  902.         HTMLCode = "&aacute;"
  903.     Case "c2"
  904.         HTMLCode = "&Acirc;"
  905.     Case "e2"
  906.         HTMLCode = "&acirc;"
  907.     Case "c3"
  908.         HTMLCode = "&Atilde;"
  909.     Case "e3"
  910.         HTMLCode = "&atilde;"
  911.     Case "c4"
  912.         HTMLCode = "&Auml;"
  913.     Case "e4"
  914.         HTMLCode = "<FONT SIZE=""-1""><SUP>TM</SUP></FONT>"
  915.     Case "c5"
  916.         HTMLCode = "&Aring;"
  917.     Case "e5"
  918.         HTMLCode = "&aring;"
  919.     Case "c6"
  920.         HTMLCode = "&AElig;"
  921.     Case "e6"
  922.         HTMLCode = "&aelig;"
  923.     Case "c7"
  924.         HTMLCode = "&Ccedil;"
  925.     Case "e7"
  926.         HTMLCode = "&ccedil;"
  927.     Case "d0"
  928.         HTMLCode = "&ETH;"
  929.     Case "f0"
  930.         HTMLCode = "&eth;"
  931.     Case "c8"
  932.         HTMLCode = "&Egrave;"
  933.     Case "e8"
  934.         HTMLCode = "&egrave;"
  935.     Case "c9"
  936.         HTMLCode = "&Eacute;"
  937.     Case "e9"
  938.         HTMLCode = "&eacute;"
  939.     Case "ca"
  940.         HTMLCode = "&Ecirc;"
  941.     Case "ea"
  942.         HTMLCode = "&ecirc;"
  943.     Case "cb"
  944.         HTMLCode = "&Euml;"
  945.     Case "eb"
  946.         HTMLCode = "&euml;"
  947.     Case "cc"
  948.         HTMLCode = "&Igrave;"
  949.     Case "ec"
  950.         HTMLCode = "&igrave;"
  951.     Case "cd"
  952.         HTMLCode = "&Iacute;"
  953.     Case "ed"
  954.         HTMLCode = "&iacute;"
  955.     Case "ce"
  956.         HTMLCode = "&Icirc;"
  957.     Case "ee"
  958.         HTMLCode = "&icirc;"
  959.     Case "cf"
  960.         HTMLCode = "&Iuml;"
  961.     Case "ef"
  962.         HTMLCode = "&iuml;"
  963.     Case "d1"
  964.         HTMLCode = "&Ntilde;"
  965.     Case "f1"
  966.         HTMLCode = "&ntilde;"
  967.     Case "d2"
  968.         HTMLCode = "&Ograve;"
  969.     Case "f2"
  970.         HTMLCode = "&ograve;"
  971.     Case "d3"
  972.         HTMLCode = "&Oacute;"
  973.     Case "f3"
  974.         HTMLCode = "&oacute;"
  975.     Case "d4"
  976.         HTMLCode = "&Ocirc;"
  977.     Case "f4"
  978.         HTMLCode = "&ocirc;"
  979.     Case "d5"
  980.         HTMLCode = "&Otilde;"
  981.     Case "f5"
  982.         HTMLCode = "&otilde;"
  983.     Case "d6"
  984.         HTMLCode = "&Ouml;"
  985.     Case "f6"
  986.         HTMLCode = "&ouml;"
  987.     Case "d8"
  988.         HTMLCode = "&Oslash;"
  989.     Case "f8"
  990.         HTMLCode = "&oslash;"
  991.     Case "d9"
  992.         HTMLCode = "&Ugrave;"
  993.     Case "f9"
  994.         HTMLCode = "&ugrave;"
  995.     Case "da"
  996.         HTMLCode = "&Uacute;"
  997.     Case "fa"
  998.         HTMLCode = "&uacute;"
  999.     Case "db"
  1000.         HTMLCode = "&Ucirc;"
  1001.     Case "fb"
  1002.         HTMLCode = "&ucirc;"
  1003.     Case "dc"
  1004.         HTMLCode = "&Uuml;"
  1005.     Case "fc"
  1006.         HTMLCode = "&uuml;"
  1007.     Case "dd"
  1008.         HTMLCode = "&Yacute;"
  1009.     Case "fd"
  1010.         HTMLCode = "&yacute;"
  1011.     Case "ff"
  1012.         HTMLCode = "&yuml;"
  1013.     Case "de"
  1014.         HTMLCode = "&THORN;"
  1015.     Case "fe"
  1016.         HTMLCode = "&thorn;"
  1017.     Case "df"
  1018.         HTMLCode = "&szlig;"
  1019.     Case "a7"
  1020.         HTMLCode = "&sect;"
  1021.     Case "b6"
  1022.         HTMLCode = "&para;"
  1023.     Case "b5"
  1024.         HTMLCode = "&micro;"
  1025.     Case "a6"
  1026.         HTMLCode = "&brvbar;"
  1027.     Case "b1"
  1028.         HTMLCode = "&plusmn;"
  1029.     Case "b7"
  1030.         HTMLCode = "&middot;"
  1031.     Case "a8"
  1032.         HTMLCode = "&uml;"
  1033.     Case "b8"
  1034.         HTMLCode = "&cedil;"
  1035.     Case "aa"
  1036.         HTMLCode = "&ordf;"
  1037.     Case "ba"
  1038.         HTMLCode = "&ordm;"
  1039.     Case "ac"
  1040.         HTMLCode = "&not;"
  1041.     Case "ad"
  1042.         HTMLCode = "&shy;"
  1043.     Case "af"
  1044.         HTMLCode = "&macr;"
  1045.     Case "b0"
  1046.         HTMLCode = "&deg;"
  1047.     Case "b9"
  1048.         HTMLCode = "&sup1;"
  1049.     Case "b2"
  1050.         HTMLCode = "&sup2;"
  1051.     Case "b3"
  1052.         HTMLCode = "&sup3;"
  1053.     Case "bc"
  1054.         HTMLCode = "&frac14;"
  1055.     Case "bd"
  1056.         HTMLCode = "&frac12;"
  1057.     Case "be"
  1058.         HTMLCode = "&frac34;"
  1059.     Case "d7"
  1060.         HTMLCode = "&times;"
  1061.     Case "f7"
  1062.         HTMLCode = "&divide;"
  1063.     Case "a2"
  1064.         HTMLCode = "&cent;"
  1065.     Case "a3"
  1066.         HTMLCode = "&pound;"
  1067.     Case "a4"
  1068.         HTMLCode = "&curren;"
  1069.     Case "a5"
  1070.         HTMLCode = "&yen;"
  1071.     Case "85"
  1072.         HTMLCode = "..."
  1073.     End Select
  1074. End Function
  1075. Function TrimifCmd(ByVal strTmp As String) As String
  1076.     Dim l As Long
  1077.     
  1078.     l = 1
  1079.     While Mid(strTmp, l, 1) = " "
  1080.         l = l + 1
  1081.     Wend
  1082.     If Mid(strTmp, l, 1) = "" Or Mid(strTmp, l, 1) = "{" Then
  1083.         strTmp = Trim(strTmp)
  1084.     Else
  1085.         If Left(strTmp, 1) = " " Then strTmp = Mid(strTmp, 2)
  1086.         strTmp = RTrim(strTmp)
  1087.     End If
  1088.     TrimifCmd = strTmp
  1089. End Function