RTF Parser Kit
| Language | Java |
|---|---|
| License | Apache-2.0 |
| Repository | github.com/joniles/rtfparserkit |
| Documentation | README, IRtfListener |
| Depends on | nothing |
| Read / write | reads RTF (events and text extraction); doesn't write RTF |
RTF Parser Kit provides two parsers. The raw parser reports RTF exactly as written: group start and end, each control word with its parameter, and text bytes. The standard parser does the work you’d otherwise repeat in every program: it tracks code pages from \ansicpg and font charsets, decodes \'hh and \uN escapes (honoring \uc), and turns special-character commands (\emdash, \lquote, …) into Unicode text. You receive events through an IRtfListener (or extend RtfListenerAdaptor and override what you need).
Included converters extract plain text to a string or stream, and RtfDump writes the RTF structure as XML for debugging. It’s used by MPXJ (project file library) to read RTF notes.
Installation#
Maven:
<dependency>
<groupId>com.github.joniles</groupId>
<artifactId>rtfparserkit</artifactId>
<version>1.16.0</version>
</dependency>
Gradle: implementation("com.github.joniles:rtfparserkit:1.16.0")
Basic usage: extract text from an RTF file#
import com.rtfparserkit.converter.text.StringTextConverter;
import com.rtfparserkit.parser.RtfStreamSource;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
public class RtfText {
public static void main(String[] args) throws Exception {
try (InputStream in = Files.newInputStream(Path.of("letter.rtf"))) {
StringTextConverter converter = new StringTextConverter();
converter.convert(new RtfStreamSource(in));
System.out.println(converter.getText());
}
}
}
How to extract text from an RTF string#
import com.rtfparserkit.parser.RtfStringSource;
StringTextConverter converter = new StringTextConverter();
converter.convert(new RtfStringSource("{\\rtf1\\ansi Hello {\\b bold} caf\\'e9\\par}"));
String text = converter.getText();
How to write text to a file in a chosen encoding#
import com.rtfparserkit.converter.text.StreamTextConverter;
try (var in = Files.newInputStream(Path.of("letter.rtf"));
var out = Files.newOutputStream(Path.of("letter.txt"))) {
new StreamTextConverter().convert(new RtfStreamSource(in), out, "UTF-8");
}
How to process RTF commands with a listener#
This listener prints the text of bold runs. The standard parser has already decoded characters:
import com.rtfparserkit.parser.IRtfParser;
import com.rtfparserkit.parser.RtfListenerAdaptor;
import com.rtfparserkit.parser.RtfStreamSource;
import com.rtfparserkit.parser.standard.StandardRtfParser;
import com.rtfparserkit.rtf.Command;
import java.util.ArrayDeque;
import java.util.Deque;
class BoldListener extends RtfListenerAdaptor {
private final Deque<Boolean> stack = new ArrayDeque<>();
private boolean bold;
@Override public void processGroupStart() { stack.push(bold); }
@Override public void processGroupEnd() { bold = stack.isEmpty() ? false : stack.pop(); }
@Override
public void processCommand(Command command, int parameter, boolean hasParameter, boolean optional) {
if (command == Command.b) bold = !hasParameter || parameter != 0; // \b or \b0
if (command == Command.plain) bold = false;
}
@Override
public void processString(String string) {
if (bold) System.out.println("bold: " + string);
}
}
IRtfParser parser = new StandardRtfParser();
try (var in = Files.newInputStream(Path.of("letter.rtf"))) {
parser.parse(new RtfStreamSource(in), new BoldListener());
}
This simple version also prints text from the font table and other destinations; check for Command.fonttbl, Command.colortbl and optional (the \* marker) to skip them.
Tips#
- Use
com.rtfparserkit.utils.RtfDumpon a sample file to see which commands and groups a document contains before writing a listener. com.rtfparserkit.utils.ImageListenercollects\pictdata if you need embedded pictures.RtfStreamSourcereads bytes; don’t wrap RTF in aReaderfirst.