Android Question [B4A] [Solved] Variable substitution in a RTF file

GabrielM

Member
Licensed User
Longtime User
I have previously been using the jPOI to the rescue example (in B4J) to substitute string variables for specific words in a MS-Word (DOC) file and it was performing great. String variables I am using inside the file text are of the format: "<<variable>>" .

Would like to try now to do something similar in B4A, though it seems the jPOI could not be used for some reasons, therefore I thought to use the RTF file format.

Seen a reference to a Java library: "com.tutego.jrtf" that has a class which is able to make variable substitution in an existing RTF file:
RtfTemplate Class

Asking for some guidance on how to use this class specifically the .inject method in B4A, so I could open an existing RTF, replace the variables (I could have them as key/value Map) and write the resulting file to another file name.
 

DonManfred

Expert
Licensed User
Longtime User
IsnĀ“t RTF just a text file?

B4X:
    File.Copy(File.DirAssets,"orgfile.rtf",File.DirInternal,"orgfile.rtf")
    Dim rtf As String = File.ReadString(File.DirInternal,"orgfile.rtf")
    ' replace the placeholder(s) in rtf
    File.WriteString(File.DirInternal,"newfile.rtf",rtf)
 
Upvote 0

GabrielM

Member
Licensed User
Longtime User
Thanks Manfred,
The RTF file its kind of big in size, and not very sure I could handled with using regex to cover some 150 different placeholders, that is why I turned to the jRTF lib, hoping it would be simpler to pass a Map with those placeholders, while I could learn some on using external jars.
 
Upvote 0

GabrielM

Member
Licensed User
Longtime User
This is what I currently try with regex, after I read line by line as strings from RTF file,
though honestly I am looking for some help on how to use that external jar - jRtf - RtfTemplate Class specifically.

B4X:
public Sub tryReplace
    Dim data As String ' this is the example RTF file read as text
    data = "We have <<ADDRESSLINE1>> as buld and <<ADDRESSLINE2>> not ready"
    '
    Dim matcher1 As Matcher
    matcher1 = Regex.Matcher("<<[^>]+>>", data)    ' regex pattern for placeholders
    Do While matcher1.Find = True
        'Log(matcher1.Match)
        Select matcher1.Match            ' care for specific placeholders
            Case "<<ADDRESSLINE1>>"
                data = data.Replace("<<ADDRESSLINE1>>", "tutego")
            Case "<<ADDRESSLINE2>>"
                data = data.Replace("<<ADDRESSLINE2>>", "Sonsbeck")
        End Select
    Loop
    '
    Log(data)
End Sub
 
Upvote 0

GabrielM

Member
Licensed User
Longtime User
What is the problem with the regex solution? Is it too slow? It can be optimized.

The regex solution just works ok, no issues.
I am trying now to pass all "placeholders" and their replacement values as a Map.
Would be great if I could optimize it, yes.
Thank you.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I wouldn't try to optimize it if it works fast enough as the optimization will make it more complicated. The idea is to build a single regex pattern and update the string in a single pass. It is done here: https://www.b4x.com/android/forum/threads/csbuilder-marking-based-on-regex-pattern.83002/#content

I am trying now to pass all "placeholders" and their replacement values as a Map.
B4X:
For Each key As String In Replacements.Keys
TryReplace(Key, Replacements.Get(Key))
Next
 
Upvote 0
Top