Jump to content

Convert RTF (Rich Text) to inline code


Stilez
 Share

Recommended Posts

This is a code generator. It takes an RTF file as source and creates reliable AutoIt code for in-line use in programs, that can be used as the contents of a rich text edit control.

Details:

Rich Text can contain formatting, screenshots and other images, which is useful (eg for in-program Help). Since RTF can be 10 - 100s of KB long and can contain non-text characters (CR, LF, Chr(0) etc), common ways to include RTF are to include it in a zipped App folder, FileInstall and extract/read it or _GUICtrlRichEdit_StreamFromFile() at runtime, or FileRead the source to a long stream of binary in a variable.

The code below is a fourth approach with some advantages. It's a code generator. It takes as source an RTF file (of any kind) and creates as output AutoIt code which faithfully assigns the exact RTF file to a variable. The advantage of this code is that the result is pure AutoIt plain text. So the rtf is completely readable, understandable and easily reviewed. Virtually no "junk" (null strings , unnecessary string termination, inefficient @CR & @LF etc) is created. Any non-text characters are converted to AutoIt macros (@CR, @LF etc) or Chr()'s. No changes are made to the content, even if an AutoIt line break is needed in the middle of some included control codes (CR/LF). The output has an almost constant length for each code line regardless of how few or many non-text characters are contained.

The code it creates can be copy-pasted directly into your code, or put in a separate file and included via #include "...", and then put in the control using _GUICtrlRichEdit_Create() or _GUICtrlRichEdit_SetText() without any runtime processing, and with no included files or file system access.

The RTF code generator:

; Rtf to Au3 converter, by Stilez
; www.autoitscript.com/forum/topic/131614-convert-rtf-rich-text-to-inline-code/

$max_AutoIt_linelength = 1000
$rtf_filename = @ScriptDir & "\MyTree.rtf"
$output_filename = @ScriptDir & "\MyTree.au3"

$rtf_description = "Picture of my tree sourced from " & $rtf_filename
$rtf_data = FileRead($rtf_filename)
$var_name = "$__My_rtf"

$au3_text = _RichTextToAU3($var_name, $rtf_description, $rtf_data, $max_AutoIt_linelength)

; Save in unicode since the comment text or file paths could include unicode.

; Note: unicode + BOM (128) format caused AutoIt itself to consistently crash for me when re#included. No BOM (256) format works fine instead. Reported at bug tracker - bug #1989

$f = FileOpen($output_filename, 2 + 256)
If $f = -1 Then 
    MsgBox(0,"","Error opening output file for writing")
    Exit
EndIf
FileWrite($f, $au3_text)
FileClose($f)

MsgBox(0,"","Rtf to Au3 completed - check out the contents of " & $output_filename & " :)")



; ---------------------------- End of demo program

; ---------------------------- Start of actual RTF functions


; $var_name - the name of an AutoIt variable which will be assigned the file content
; $rtf_description - an optional description (self-commenting output)
; $rtf_data - the actual raw rtf to be converted to au3 - it can include control codes, unicode, whatever
; $max_AutoIt_linelength - the approx max length of a line of output code (may be a few chars longer)

Func _RichTextToAU3($var_name, $rtf_description, ByRef $rtf_data, $max_AutoIt_linelength = 2000)
    $charpointer = 1
    $result = "; " & $var_name & " holds the contents of: """ & $rtf_description & """" & @CRLF & @CRLF & $var_name & " = "
    $output_chunk = ""
    $first_time = True

    While _GetRtfSafeChunk($rtf_data, $charpointer, $output_chunk, $max_AutoIt_linelength)
        If $first_time Then
            $result &= $output_chunk
            $first_time = False
        Else
            $result &= @CRLF & $var_name & " &= " & $output_chunk
        EndIf
    WEnd
    
    if $first_time = True Then $result &= """"""
    Return $result & @CRLF

EndFunc   ;==> _RichTextToAU3


; Read and transcribe from current position in source text into au3 format until our output reaches max allowed length.
; Return True if we did something, or False if we're done and nothing needed transcribing (end of text)
; ByRef used to minimize copying in memory of potentially very long strings.

Func _GetRtfSafeChunk(ByRef $text, ByRef $charpointer, ByRef $output_chunk, $max_AutoIt_linelength)
    $textlen = StringLen($text)
    If $charpointer > $textlen Then Return False
    
    $output_chunk = """"
    $stringmode = True
        
    While $charpointer <= $textlen And StringLen($output_chunk) < $max_AutoIt_linelength
        
        $c = StringMid($text, $charpointer, 1)
        $ca = Asc($c)
        
        If $stringmode And ($ca < 32 Or $ca > 126) Then
            $output_chunk &= """"
            $stringmode = False
        ElseIf Not $stringmode And ($ca >= 32 And $ca <= 126) Then
            $output_chunk &= " & """
            $stringmode = True
        EndIf
        
        Select
            Case $c = @CR
                If StringMid($text, $charpointer, 2) = @CRLF Then
                    $output_chunk &= " & @CRLF"
                    $charpointer += 1
                Else
                    $output_chunk &= " & @CR"
                EndIf
            Case $c = @LF
                $output_chunk &= " & @LF"
            Case $c = @TAB
                $output_chunk &= " & @TAB"
            Case $ca < 32 Or $ca > 126
                $output_chunk &= " & Chr(" & Asc($c) & ")"
            Case $c = """"
                $output_chunk &= """"""
            Case Else
                $output_chunk &= $c
        EndSelect
        $charpointer += 1
        
    WEnd
    
    If $stringmode Then $output_chunk &= """"
    Return True
    
EndFunc   ;==>_GetRtfSafeChunk

Example of style of output (extract of a real file):

; $__My_rtf holds the contents of: "Picture of my tree sourced from C:\Users\MyUsername\Desktop\MyTree.rtf"

$__My_rtf = "{\rtf1\ansi\ansicpg1252\deff0\deflang2057{\fonttbl{\f0\fnil\fcharset0 Calibri;}}" & @CRLF & "{\colortbl ;\red204\green204\blue204;\red0\green0\blue0;}" & @CRLF & "{\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\sl276\slmult1\qc\cf1\highlight2\lang9\f0\fs22  Hello world! \cf0\highlight0\par" & @CRLF & "\pard\sl240\slmult1\qc{\pict\wmetafile8\picw1773\pich1508\picwgoal1005\pichgoal855 " & @CRLF & "000c0239004300030000001e0004000000070104000400c00..." & @CRLF
$__My_rtf &= "60099ffff003399cc00ffffcc00003300" & @CRLF & "0099cc9900ffcccc00330033000000000000000000000000000000000000000000000000000000" & @CRLF & "000000000000000000000000000000000000000000000000000000000000000000000000000000" & @CRLF & "000000000000000000000000000000000000000000000000000000000000000000000000000000" & @CRLF & "000000000000000000000000000000000000000000000000000000000000000000000000000000" & @CRLF & "0000000000000000000000000000000000000000000"
$__My_rtf &= "00000000000000000000000000000000000" & @CRLF & "000000000000000000000000000000000000000000000000000000000000000000000000000000" & @CRLF & "000000000000000000000000000000000000000000000000000000000000000000000000000000" & @CRLF & "000000000000000000000000000000000000000000000000000000000000000000000000000000" & @CRLF & "000000000000000000000000000000000000000000000000000000000000000000000000000000" & @CRLF & "00000000000000000000000000000000000000000"
$__My_rtf &= "0000000000000000000000000000000000000" & @CRLF & "000000000000000000000000000000000000000000000000000000010101010101010101010101" & @CRLF & "0b010b0906030b0208160607010101010101010101010160010101010101010101010101020102" & @CRLF & "020101010101010101010101010001010101010101010101010101010101010209030a0c0c0a0a" & @CRLF & "010101010101010101010101010b060b07060a0616020101210101010101010101010101010101" & @CRLF & "010101010104060a1d010101010101010101010"
$__My_rtf &= "7060a110606060c0d050101010101010101010101000101010101" & @CRLF & "01010101020105060904020b0c0a060c0d0a0a060a0f15100a0f090a0a100a0d0c0f0c0d0d0606" & @CRLF & "0b010b0906030b0208160607010101010101010101010160010101010101010101010101020102" & @CRLF & "020101010101010101010101010001010101010101010101010101010101010209030a0c0c0a0a" & @CRLF & "01010101010102010707080709060a0606060802030a06030b0101010101010101010101010101" & @CRLF & "01010101010101010101010"
$__My_rtf &= "1000101010101010101010101010101010101010101010101010101" & @CRLF & "010102030405060307010801020101010101010101010101010101010101010101010101010101" & @CRLF & "010100040000002701ffff030000000000" & @CRLF & "}\par" & @CRLF & "This is my tree!\par" & @CRLF & "}" & @CRLF
Edited by Stilez
Link to comment
Share on other sites

So, the interest , is just to easily embed richedit text to an AutoIt script ?

To embed it as code, rather than (eg) FileInstall() or binary, yes. And to have a way to convert an RTF file or string to pure ascii text that handles CR/LF correctly. Edited by Stilez
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...