Hallo Ihr lieben, ich sitze immernoch an meinem Dokument-Verwaltungsprogramm.
Derzeit bin ich gerade dabei verschiedene Dateikonvertierungen zu implementieren. Dazu bediene ich mich unter anderem an PDFSharp und Migradoc.
Da im Netz kaum etwas zu finden ist, wie man nun RTF zu Migradoc parst und schließlich zu PDF umwandelt, dachte ich mir, dass ich mich der Sache einmal annehme.
Grund dafür ist auch, dass ich Docx-Dateien nicht direkt einlesen kann und zu RTF umwandle und somit sollte ich mir in Punkto RTF etwas mehr Mühe geben.
Hab ihr vielleicht Lust und Zeit mir hier etwas zu helfen, da ich gerade nicht so genau weis, ob ich einen guten Ansatz gewählt habe und wie ich nun von meiner Strukturierung mit Migradoc zusammen komme.
Hier nachfolgend mein Ansatz:
Spoiler anzeigen
Die Verwendung kann so aussehen:
- Form mit Richtextbox + PropertyGrid
RTF-Inhalt für die Richtextbox ist im Anhang!
Ich würde mich über Tipps zur Verbesserung und allgemeine Mithilfe echt freuen!
Danke und Gruß Hassowuff
Derzeit bin ich gerade dabei verschiedene Dateikonvertierungen zu implementieren. Dazu bediene ich mich unter anderem an PDFSharp und Migradoc.
Da im Netz kaum etwas zu finden ist, wie man nun RTF zu Migradoc parst und schließlich zu PDF umwandelt, dachte ich mir, dass ich mich der Sache einmal annehme.
Grund dafür ist auch, dass ich Docx-Dateien nicht direkt einlesen kann und zu RTF umwandle und somit sollte ich mir in Punkto RTF etwas mehr Mühe geben.
Hab ihr vielleicht Lust und Zeit mir hier etwas zu helfen, da ich gerade nicht so genau weis, ob ich einen guten Ansatz gewählt habe und wie ich nun von meiner Strukturierung mit Migradoc zusammen komme.
Hier nachfolgend mein Ansatz:
VB.NET-Quellcode
- Imports System.Text
- Imports System.Text.RegularExpressions
- Public Class RTF_Parser
- Public Property raw As String = ""
- Public Property rawLines As List(Of String) = New List(Of String)
- Public Property fontList As List(Of Font) = New List(Of Font)
- Public Property colorList As List(Of Color) = New List(Of Color)
- Public Property commands As List(Of String) = New List(Of String)
- Public Sub New(rawRtf As String)
- raw = rawRtf
- colorList.Add(Color.Black) ' Standard-Color: Black / Colorindexing in RTF begins by 1
- Parse()
- End Sub
- Public Sub Parse()
- SplitLines() ' Split lines by CrLf to List(of String)
- GenerateFontList() ' Read RTF FontTable
- GenerateColorList() ' Read RTF ColorTable
- ReadLines() ' Read each command in each line
- End Sub
- Private Sub SplitLines()
- Dim lines As String() = raw.Split(vbNewLine)
- For Each line As String In lines
- If line.Trim <> "" Then rawLines.Add(line)
- Next
- End Sub
- Private fntListIdx As Integer = 0
- Private Sub GenerateFontList()
- ' Search line with fonttable and save the index to "fntListIdx"
- For i As Integer = 0 To rawLines.Count - 1
- If rawLines(i).Contains("{\fonttbl") Then
- fntListIdx = i
- Exit For
- End If
- Next
- ' Match the name of each font in fonttable
- Dim matches As MatchCollection = Regex.Matches(rawLines(fntListIdx), "{\\f[A-z0-9]*\s]*([A-z0-9\s]*);}")
- For Each match As Match In matches
- If match.Success = True And match.Groups.Count = 2 Then
- ' Save it to a List(of Font)
- fontList.Add(New Font(match.Groups(1).Value, 11.25))
- End If
- Next
- End Sub
- Private colListIdx As Integer = 0
- Private Sub GenerateColorList()
- ' Search line with colortable and save the index to "colListIdx"
- For i As Integer = 0 To rawLines.Count - 1
- If rawLines(i).Contains("{\colortbl") Then
- colListIdx = i
- Exit For
- End If
- Next
- ' Match the Values (red, green, blue) for each Color in table
- Dim matches As MatchCollection = Regex.Matches(rawLines(colListIdx), "\\red([0-9]*)\\green([0-9]*)\\blue([0-9]*);")
- For Each match As Match In matches
- If match.Success And match.Groups.Count = 4 Then
- Dim r As Integer = Integer.Parse(match.Groups(1).Value)
- Dim g As Integer = Integer.Parse(match.Groups(2).Value)
- Dim b As Integer = Integer.Parse(match.Groups(3).Value)
- ' Save it to an List(of Color)
- colorList.Add(Color.FromArgb(r, g, b))
- End If
- Next
- End Sub
- Private Sub ReadLines()
- ' Startline after Color- and Fonttable
- Dim s As Integer = IIf(fntListIdx > colListIdx, fntListIdx, colListIdx) + 1
- ' Holder for free Text (ignores Linebreaks)
- Dim txt As String = ""
- ' Go through all lines
- For lineIdx As Integer = s To rawLines.Count - 1
- Dim lineStr As String = rawLines(lineIdx) ' original Raw-Line
- ' Holders for command name and value
- Dim befStarted As Boolean = False ' is true if char "\" is passed
- Dim befName As String = "" ' becomes the command charwise if befStarted = true
- Dim befVal As String = "" ' becomes the value for the command (only numeric)
- For Each lineLet As Char In lineStr
- If lineLet = "\" Then ' command begins!
- If befStarted = False Then ' is there an active command? Yes:
- addCommand("txt", txt) ' - save the free text
- txt = "" ' - reset the free text
- befStarted = True ' - start command-recording
- Else ' no? Then:
- addCommand(befName, befVal) ' - command completed -> save it!
- befStarted = False ' - stop command-recording
- befName = "" ' - reset command-name
- befVal = "" ' - reset command-value
- End If
- ElseIf lineLet = " " Then ' Spacechar (?in freetext or after last command?)
- If befStarted = True Then ' is there an active command? Yes:
- addCommand(befName, befVal) ' - command completed -> save it!
- befStarted = False ' - stop command-recording
- befName = "" ' - reset command-name
- befVal = "" ' - reset command-value
- Else ' no? Then:
- txt &= lineLet ' - add Spacechar to freetext
- End If
- ElseIf IsNumeric(lineLet) = True Then ' Numeric char! In freetext or command-value?
- If befStarted = True Then ' is there an active command? Yes:
- befVal &= lineLet ' - add Number to command-value
- Else ' no? Then:
- txt &= lineLet ' - add Number to freetext
- End If
- Else ' All other chars (Letters and so on..)
- If befStarted = True Then ' is there an active command? Yes:
- befName &= lineLet ' - add char to command-name
- Else ' no? Then:
- txt &= lineLet ' - add char to freetext
- End If
- End If
- Next ' After this "Next" end of Line is reached!
- If befStarted = True Then ' is command-recording on? Yes:
- addCommand(befName, befVal) ' - command completed -> save it!
- befStarted = False ' - stop command-recording
- befName = "" ' - reset command-name
- befVal = "" ' - reset command-value
- End If
- Next
- End Sub
- Private Sub addCommand(name As String, value As String)
- commands.Add(name & "=" & value) ' Save name and value to an List(of String) -> for Debug!
- Select Case name
- Case "pard" ' begin of Paragraph and end of last Paragraph
- ' Value = ""
- Case "par" ' linebreak
- ' Value = ""
- Case "f" ' font-selector
- ' Value = indexnumber at Fontlist
- Case "fs" ' font-size
- ' Value = size in half-points
- Case "cf" ' font-color
- ' Value (>0) = indexnumber at colorlist / Value (=0) = end of the last color
- Case "b" ' bold font
- ' Value ("") = Start / Value ("0") = End
- Case "i" ' italic font
- ' Value ("") = Start / Value ("0") = Ende
- Case "ul" ' underlining start
- ' Value = ""
- Case "ulnone" ' underlining stop/end
- ' Value = ""
- Case "tab" ' text indent
- ' Value = ""
- Case "'B" ' symbol
- ' Value (7) = · (Point for Lists)
- Case Else
- Debug.WriteLine("Unknown Command: " & name & "=" & value)
- End Select
- End Sub
- End Class
Die Verwendung kann so aussehen:
- Form mit Richtextbox + PropertyGrid
RTF-Inhalt für die Richtextbox ist im Anhang!
Ich würde mich über Tipps zur Verbesserung und allgemeine Mithilfe echt freuen!
Danke und Gruß Hassowuff
__________________________
01: CLS : SCREEN 12
02: LINE (0, 20)-(640, 22), 15, BF
03: ECHO "MFG HASSOWUFF"
[F5]
01: CLS : SCREEN 12
02: LINE (0, 20)-(640, 22), 15, BF
03: ECHO "MFG HASSOWUFF"
[F5]