Advertisement
Guest User

Untitled

a guest
Dec 10th, 2016
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.31 KB | None | 0 0
  1. Option Explicit
  2. '
  3. ' BbCodes supported:
  4. ' b, i, u
  5. ' size={FontSize}
  6. ' color={ColorNameOrValue}
  7. ' font={FontName}
  8. ' table={Col1_Width},{Col2_Width}, ...[;[TableLeftOffset],[ColumnLeftOffset]]
  9. ' row={Col1_BackColor},{Col2_BackColor}, ...;<<col1_border>>;<<col2_border>>;...]
  10. ' <<colN_border>>:=[BorderLeftColor] [BorderLeftWidth],[BorderTopColor] [BorderTopWidth],[BorderRightColor] [BorderRightWidth],[BorderBottomColor] [BorderBottomWidth]
  11. ' col
  12. '
  13. ' e.g.
  14. ' [table=100,200,300]
  15. ' [row]--A--[col]--B--[col]--C--[/row]
  16. ' [row]1[col]test[col]value[/row]
  17. ' [/table]
  18. '
  19. Private Declare Function WideCharToMultiByte Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, ByVal lpUsedDefaultChar As Long) As Long
  20.  
  21. Private Const STR_BBCODE_TAGS As String = "[[]|[b]|[/b]|[i]|[/i]|[u]|[/u]|[size=|[/size]|[color=|[/color]|[url=|[/url]|[font=|[/font]|[right]|[/right]|[center]|[/center]|[table=|[/table]|[row]|[row=|[/row]|[col]"
  22. Private Const STR_BBCODE_COLOR_NAMES As String = "black|red|green|blue|cyan|magenta|yellow|grey|white"
  23. Private Const STR_BBCODE_COLOR_RGBS As String = "&H000000|&HFF0000|&H00FF00|&H0000FF|&H00FFFF|&HFF00FF|&HFFFF00|&HC0C0C0|&HFFFFFF"
  24. Private Const STR_BBCODE_RTF_PREFIX As String = "{\rtf1"
  25. Private Const STR_BBCODE_RTF_SUFFIX As String = "}"
  26. Private Const STR_BBCODE_FONTS_PREFIX As String = "{\fonttbl "
  27. Private Const STR_BBCODE_FONTS_SUFFIX As String = "}"
  28. Private Const STR_BBCODE_COLORS_PREFIX As String = "{\colortbl "
  29. Private Const STR_BBCODE_COLORS_SUFFIX As String = "}"
  30.  
  31. Private Enum UcsBBCodeTags
  32. ucsTagBracket
  33. ucsTagBold
  34. ucsTagBoldEnd
  35. ucsTagItalic
  36. ucsTagItalicEnd
  37. ucsTagUnderline
  38. ucsTagUnderlineEnd
  39. ucsTagSize
  40. ucsTagSizeEnd
  41. ucsTagColor
  42. ucsTagColorEnd
  43. ucsTagUrl
  44. ucsTagUrlEnd
  45. ucsTagFont
  46. ucsTagFontEnd
  47. ucsTagRight
  48. ucsTagRightEnd
  49. ucsTagCenter
  50. ucsTagCenterEnd
  51. ucsTagTable
  52. ucsTagTableEnd
  53. ucsTagRow
  54. ucsTagRowPlain
  55. ucsTagRowEnd
  56. ucsTagCol
  57. End Enum
  58.  
  59. Private Sub PrintError(sFunc As String)
  60. Debug.Print sFunc, Error$
  61. End Sub
  62.  
  63. Public Function BbCode2Rtf(sText As String, oFont As StdFont) As String
  64. Const FUNC_NAME As String = "BbCode2Rtf"
  65. Dim vTags As Variant
  66. Dim vColorNames As Variant
  67. Dim vColorRGBs As Variant
  68. Dim cStack As Collection
  69. Dim cFonts As Collection
  70. Dim cColors As Collection
  71. Dim lPos As Long
  72. Dim lTagStart As Long
  73. Dim lTagEnd As Long
  74. Dim sRetVal As String
  75. Dim eTag As UcsBBCodeTags
  76. Dim lCurSize As Long
  77. Dim lCurColor As Long
  78. Dim lCurFont As Long
  79. Dim lTemp As Long
  80. Dim lIdx As Long
  81. Dim lJdx As Long
  82. Dim sValue As String
  83. Dim sParFmt As String
  84. Dim vColumns As Variant
  85. Dim vOffsets As Variant
  86. Dim vSplit As Variant
  87. Dim vBgColors As Variant
  88. Dim vBorders As Variant
  89. Dim vBorderDef As Variant
  90.  
  91. On Error GoTo EH
  92. '--- prepare lookup arrays
  93. vTags = Split(STR_BBCODE_TAGS, "|")
  94. vColorNames = Split(STR_BBCODE_COLOR_NAMES, "|")
  95. vColorRGBs = Split(STR_BBCODE_COLOR_RGBS, "|")
  96. '--- prepare collections
  97. Set cStack = New Collection
  98. Set cFonts = New Collection
  99. Set cColors = New Collection
  100. cFonts.Add oFont.Name, oFont.Name
  101. cColors.Add 0, "#0"
  102. '--- init default current values
  103. lCurFont = 1
  104. lCurSize = Round(oFont.Size * 2)
  105. lCurColor = 0
  106. sRetVal = "\f" & lCurFont & "\fs" & lCurSize & "\cf" & lCurColor & vbCrLf
  107. '--- parse
  108. lPos = 1
  109. Do While lPos <= Len(sText)
  110. lTagStart = InStr(lPos, sText, "[")
  111. If lTagStart > 0 Then
  112. lTagEnd = InStr(lTagStart, sText, "]")
  113. Else
  114. lTagEnd = 0
  115. lTagStart = Len(sText) + 1
  116. End If
  117. sRetVal = sRetVal & RtfEscape(Mid(sText, lPos, lTagStart - lPos), sParFmt)
  118. lPos = lTagStart + 1
  119. If lTagStart > 0 And lTagEnd > 0 Then
  120. For eTag = 0 To UBound(vTags)
  121. If LCase(Mid(sText, lTagStart, Len(vTags(eTag)))) = vTags(eTag) And _
  122. (Right(vTags(eTag), 1) <> "]" Or lTagEnd = lTagStart + Len(vTags(eTag))) - 1 Then
  123. Exit For
  124. End If
  125. Next
  126. Select Case eTag
  127. Case ucsTagBracket
  128. sRetVal = sRetVal & RtfEscape("[", sParFmt)
  129. Case ucsTagBold
  130. sRetVal = sRetVal & "\b "
  131. Case ucsTagBoldEnd
  132. sRetVal = sRetVal & "\b0 "
  133. Case ucsTagItalic
  134. sRetVal = sRetVal & "\i "
  135. Case ucsTagItalicEnd
  136. sRetVal = sRetVal & "\i0 "
  137. Case ucsTagUnderline
  138. sRetVal = sRetVal & "\ul "
  139. Case ucsTagUnderlineEnd
  140. sRetVal = sRetVal & "\ul0 "
  141. Case ucsTagSize
  142. cStack.Add Array(ucsTagSize, lCurSize)
  143. sValue = Trim(pvBbCodeGetValue(Mid(sText, lTagStart, lTagEnd - lTagStart + 1)))
  144. If Right(sValue, 1) = "%" Then
  145. lTemp = Round(2 * Val(sValue) * oFont.Size / 100, 0)
  146. Else
  147. lTemp = Round(2 * Val(sValue), 0)
  148. End If
  149. If lTemp > 0 Then
  150. lCurSize = lTemp
  151. sRetVal = sRetVal & "\fs" & lCurSize & " "
  152. End If
  153. Case ucsTagSizeEnd
  154. For lIdx = cStack.Count To 1 Step -1
  155. If cStack(lIdx)(0) = ucsTagSize Then
  156. lCurSize = cStack(lIdx)(1)
  157. sRetVal = sRetVal & "\fs" & lCurSize & " "
  158. cStack.Remove lIdx
  159. Exit For
  160. End If
  161. Next
  162. If lIdx < 1 Then
  163. GoTo UnknownTag
  164. End If
  165. Case ucsTagColor
  166. sValue = LCase(pvBbCodeGetValue(Mid(sText, lTagStart, lTagEnd - lTagStart + 1)))
  167. cStack.Add Array(ucsTagColor, lCurColor)
  168. lCurColor = pvBbCodeGetColorIdx(sValue, cColors, vColorNames, vColorRGBs)
  169. sRetVal = sRetVal & "\cf" & lCurColor & " "
  170. Case ucsTagColorEnd
  171. For lIdx = cStack.Count To 1 Step -1
  172. If cStack(lIdx)(0) = ucsTagColor Then
  173. lCurColor = cStack(lIdx)(1)
  174. sRetVal = sRetVal & "\cf" & lCurColor & " "
  175. cStack.Remove lIdx
  176. Exit For
  177. End If
  178. Next
  179. If lIdx < 1 Then
  180. GoTo UnknownTag
  181. End If
  182. Case ucsTagUrl
  183. Case ucsTagUrlEnd
  184. Case ucsTagFont
  185. sValue = pvBbCodeGetValue(Mid(sText, lTagStart, lTagEnd - lTagStart + 1))
  186. On Error Resume Next
  187. cFonts.Add sValue, sValue
  188. On Error GoTo EH
  189. For lIdx = 1 To cFonts.Count
  190. If LCase(cFonts(lIdx)) = LCase(sValue) Then
  191. Exit For
  192. End If
  193. Next
  194. cStack.Add Array(ucsTagFont, lCurFont)
  195. lCurFont = lIdx
  196. sRetVal = sRetVal & "\f" & lCurFont & " "
  197. Case ucsTagFontEnd
  198. For lIdx = cStack.Count To 1 Step -1
  199. If cStack(lIdx)(0) = ucsTagFont Then
  200. lCurFont = cStack(lIdx)(1)
  201. sRetVal = sRetVal & "\f" & lCurFont & " "
  202. cStack.Remove lIdx
  203. Exit For
  204. End If
  205. Next
  206. If lIdx < 1 Then
  207. GoTo UnknownTag
  208. End If
  209. Case ucsTagRight
  210. sParFmt = "\qr "
  211. sRetVal = sRetVal & sParFmt
  212. Case ucsTagRightEnd
  213. sParFmt = vbNullString
  214. Case ucsTagCenter
  215. sParFmt = "\qc "
  216. sRetVal = sRetVal & sParFmt
  217. Case ucsTagCenterEnd
  218. sParFmt = vbNullString
  219. Case ucsTagTable
  220. sValue = pvBbCodeGetValue(Mid(sText, lTagStart, lTagEnd - lTagStart + 1))
  221. cStack.Add Array(ucsTagTable, sValue)
  222. sParFmt = vbNullString
  223. If Mid(sText, lTagEnd + 1, 2) = vbCrLf Then
  224. lTagEnd = lTagEnd + 2
  225. End If
  226. Case ucsTagTableEnd
  227. For lIdx = cStack.Count To 1 Step -1
  228. If cStack(lIdx)(0) = ucsTagTable Then
  229. sRetVal = sRetVal & "\pard "
  230. cStack.Remove lIdx
  231. Exit For
  232. End If
  233. Next
  234. If lIdx < 1 Then
  235. GoTo UnknownTag
  236. End If
  237. If Mid(sText, lTagEnd + 1, 2) = vbCrLf Then
  238. lTagEnd = lTagEnd + 2
  239. End If
  240. Case ucsTagRow, ucsTagRowPlain
  241. For lIdx = cStack.Count To 1 Step -1
  242. If cStack(lIdx)(0) = ucsTagTable Then
  243. sValue = cStack(lIdx)(1)
  244. Exit For
  245. End If
  246. Next
  247. If lIdx < 1 Then
  248. GoTo UnknownTag
  249. End If
  250. '--- columns
  251. vSplit = Split(sValue, ";")
  252. vColumns = Split(At(vSplit, 0), ",")
  253. vOffsets = Split(At(vSplit, 1), ",")
  254. sRetVal = sRetVal & "\trowd\trgaph" & At(vOffsets, 0, "70") & "\trleft" & At(vOffsets, 1, "0")
  255. 'sRetVal = sRetVal & "\trbrdrl\brdrs\brdrw10\brdrcf0 \trbrdrt\brdrs\brdrw10\brdrcf0 \trbrdrr\brdrs\brdrw10\brdrcf0 \trbrdrb\brdrs\brdrw10\brdrcf0" & vbCrLf
  256. '--- borders
  257. sValue = pvBbCodeGetValue(Mid(sText, lTagStart, lTagEnd - lTagStart + 1))
  258. vSplit = Split(sValue, ";")
  259. vBgColors = Split(At(vSplit, 0), ",")
  260. lTemp = C_Lng(At(vOffsets, 1, "0"))
  261. For lIdx = 0 To UBound(vColumns)
  262. If LenB(At(vBgColors, lIdx)) <> 0 Then
  263. sRetVal = sRetVal & "\clcbpat" & pvBbCodeGetColorIdx(At(vBgColors, lIdx), cColors, vColorNames, vColorRGBs)
  264. End If
  265. lTemp = lTemp + C_Lng(vColumns(lIdx))
  266. vBorders = Split(At(vSplit, lIdx + 1), ",")
  267. For lJdx = 0 To 3
  268. If LenB(At(vBorders, lJdx)) <> 0 Then
  269. vBorderDef = Split(vBorders(lJdx), " ")
  270. sRetVal = sRetVal & "\clbrdr" & Mid("ltrb", lJdx + 1, 1) & "\brdrs\brdrw" & C_Lng(At(vBorderDef, 1, "10")) & "\brdrcf" & pvBbCodeGetColorIdx(At(vBorderDef, 0), cColors, vColorNames, vColorRGBs) & vbCrLf
  271. End If
  272. Next
  273. sRetVal = sRetVal & "\cellx" & lTemp & vbCrLf
  274. Next
  275. sRetVal = sRetVal & "\pard\intbl "
  276. Case ucsTagRowEnd
  277. sRetVal = sRetVal & "\cell\row" & vbCrLf
  278. If Mid(sText, lTagEnd + 1, 2) = vbCrLf Then
  279. lTagEnd = lTagEnd + 2
  280. End If
  281. Case ucsTagCol
  282. sRetVal = sRetVal & "\cell\pard\intbl "
  283. Case Else
  284. UnknownTag:
  285. '--- unknown tag
  286. sRetVal = sRetVal & RtfEscape(Mid(sText, lTagStart, lTagEnd - lTagStart + 1), sParFmt)
  287. End Select
  288. lPos = lTagEnd + 1
  289. ElseIf lPos <= Len(sText) Then
  290. sRetVal = sRetVal & "["
  291. End If
  292. Loop
  293. BbCode2Rtf = STR_BBCODE_RTF_PREFIX
  294. '--- dump fonts table
  295. BbCode2Rtf = BbCode2Rtf & vbCrLf & STR_BBCODE_FONTS_PREFIX
  296. For lIdx = 1 To cFonts.Count
  297. BbCode2Rtf = BbCode2Rtf & "{\f" & lIdx & "\fcharset204 " & cFonts(lIdx) & ";}"
  298. Next
  299. BbCode2Rtf = BbCode2Rtf & STR_BBCODE_FONTS_SUFFIX
  300. '--- dump colors table
  301. BbCode2Rtf = BbCode2Rtf & vbCrLf & STR_BBCODE_COLORS_PREFIX
  302. For lIdx = 1 To cColors.Count
  303. lTemp = cColors(lIdx)
  304. If lTemp = 0 Then
  305. BbCode2Rtf = BbCode2Rtf & ";"
  306. Else
  307. BbCode2Rtf = BbCode2Rtf & _
  308. "\red" & ((lTemp \ &H10000) And &HFF&) & _
  309. "\green" & ((lTemp \ &H100&) And &HFF&) & _
  310. "\blue" & (lTemp And &HFF&) & ";"
  311. End If
  312. Next
  313. BbCode2Rtf = BbCode2Rtf & STR_BBCODE_COLORS_SUFFIX
  314. '--- insert body & suffix
  315. BbCode2Rtf = BbCode2Rtf & vbCrLf & sRetVal & vbCrLf & STR_BBCODE_RTF_SUFFIX
  316. Exit Function
  317. EH:
  318. PrintError FUNC_NAME
  319. Resume Next
  320. End Function
  321.  
  322.  
  323. Public Function RtfEscape(sText As String, Optional sParFmt As String) As String
  324. ' RtfEscape = Replace(Replace(Replace(Replace(Replace(Replace(Replace(sText, "\" & vbCrLf, Chr(127)), "\", "\\"), "{", "\{"), "}", "\}"), vbTab, "\tab "), vbCrLf, "\par" & vbCrLf & sParFmt), Chr(127), "\line" & vbCrLf)
  325. Dim lSize As Long
  326. Dim baBuffer() As Byte
  327. Dim lIdx As Long
  328. Dim nNext As Byte
  329.  
  330. lSize = WideCharToMultiByte(1251, 0, StrPtr(sText), Len(sText), 0, 0, 0, 0)
  331. If lSize > 0 Then
  332. ReDim baBuffer(0 To lSize - 1) As Byte
  333. Call WideCharToMultiByte(1251, 0, StrPtr(sText), Len(sText), VarPtr(baBuffer(0)), lSize, 0, 0)
  334. Do While lIdx <= UBound(baBuffer)
  335. If lIdx < UBound(baBuffer) Then
  336. nNext = baBuffer(lIdx + 1)
  337. Else
  338. nNext = 0
  339. End If
  340. Select Case baBuffer(lIdx)
  341. Case 92 ' "\"
  342. If nNext = 13 Then ' vbCr
  343. RtfEscape = RtfEscape & "\line" & vbCrLf
  344. lIdx = lIdx + 2
  345. Else
  346. RtfEscape = RtfEscape & "\\"
  347. End If
  348. Case 123, 125 ' "{", "}"
  349. RtfEscape = RtfEscape & "\" & Chr$(baBuffer(lIdx))
  350. Case 9 ' vbTab
  351. RtfEscape = RtfEscape & "\tab "
  352. Case 10 ' vbLf
  353. RtfEscape = RtfEscape & "\par" & vbCrLf & sParFmt
  354. Case 13 ' vbCr
  355. RtfEscape = RtfEscape & "\par" & vbCrLf & sParFmt
  356. If nNext = 10 Then ' vbLf
  357. lIdx = lIdx + 1
  358. End If
  359. Case Else
  360. If baBuffer(lIdx) < &H80 Then
  361. RtfEscape = RtfEscape & Chr$(baBuffer(lIdx))
  362. Else
  363. RtfEscape = RtfEscape & "\'" & Hex(baBuffer(lIdx))
  364. End If
  365. End Select
  366. lIdx = lIdx + 1
  367. Loop
  368. End If
  369. End Function
  370.  
  371. Private Function pvBbCodeGetValue(sTag As String) As String
  372. If InStr(Mid(sTag, 2, Len(sTag) - 2), "=") > 0 Then
  373. pvBbCodeGetValue = Split(Mid(sTag, 2, Len(sTag) - 2), "=")(1)
  374. End If
  375. End Function
  376.  
  377. Private Function pvBbCodeGetColorIdx(sValue As String, cColors As Collection, vColorNames As Variant, vColorRGBs As Variant) As Long
  378. Dim lTemp As Long
  379. Dim lIdx As Long
  380.  
  381. If Left(sValue, 1) = "#" Then
  382. lTemp = C_Lng("&H" & Mid(sValue, 2))
  383. Else
  384. lTemp = 0
  385. For lIdx = 0 To UBound(vColorNames)
  386. If vColorNames(lIdx) = sValue Then
  387. lTemp = vColorRGBs(lIdx)
  388. Exit For
  389. End If
  390. Next
  391. End If
  392. On Error Resume Next
  393. cColors.Add lTemp, "#" & lTemp
  394. On Error GoTo 0
  395. For lIdx = 1 To cColors.Count
  396. If cColors(lIdx) = lTemp Then
  397. pvBbCodeGetColorIdx = lIdx - 1
  398. Exit For
  399. End If
  400. Next
  401. End Function
  402.  
  403. Public Function At(Data As Variant, ByVal Index As Long, Optional Default As String) As String
  404. On Error Resume Next
  405. At = Default
  406. At = C_Str(Data(Index))
  407. On Error GoTo 0
  408. End Function
  409.  
  410. Public Function C_Str(Value As Variant) As String
  411. On Error Resume Next
  412. C_Str = CStr(Value)
  413. On Error GoTo 0
  414. End Function
  415.  
  416. Public Function C_Lng(Value As Variant) As Long
  417. On Error Resume Next
  418. C_Lng = CLng(Value)
  419. On Error GoTo 0
  420. End Function
  421.  
  422. Private Sub Form_Load()
  423. Debug.Print BbCode2Rtf("This is a [b]bold[/b] test", Me.Font)
  424. Debug.Print BbCode2Rtf("[table=100,200,300][row]--A--[col]--B--[col]--C--[/row][row]1[col]test[col]value[/row][/table]", Me.Font)
  425. End Sub
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement