All formats

ruby-rtf

LanguageRuby
LicenseMIT
Repositorygithub.com/dj2/Ruby-RTF
DocumentationREADME, example converter in bin/rtf_parse
Depends onnothing
Read / writereads RTF; doesn't write RTF

ruby-rtf parses an RTF string with RubyRTF::Parser.new.parse(src) and returns a RubyRTF::Document. The document has font_table, colour_table (alias color_table) and sections. Each section is a hash with :text and :modifiers: :bold, :italic, :underline, :font, :font_size, :foreground_colour, :paragraph, :newline, :tab, special characters like :emdash and :rquote, and :table for tables. Pictures come through as sections with :picture and hex data.

The parser covers common documents but not the whole spec. By default it warns about control words it doesn’t know; pass unknown_control_warning_enabled: false to silence that. The last gem release (0.0.5) is from 2020.

Installation#

Shell
gem install ruby-rtf

Basic usage: extract text from an RTF file#

Ruby
require "ruby-rtf"

doc = RubyRTF::Parser.new(unknown_control_warning_enabled: false).parse(File.read("letter.rtf"))

text = +""
doc.sections.each do |section|
  mods = section[:modifiers]
  if mods[:paragraph]
    text << "\n"
  elsif mods[:tab]
    text << "\t"
  end
  text << section[:text].to_s.dup.force_encoding("UTF-8")   # \line sections carry "\n"
end
puts text

How to convert RTF to simple HTML#

Ruby
require "cgi"
require "ruby-rtf"

doc = RubyRTF::Parser.new(unknown_control_warning_enabled: false).parse(File.read("letter.rtf"))
html = +"<p>"
doc.sections.each do |s|
  m = s[:modifiers]
  html << "</p>\n<p>" if m[:paragraph]
  html << "<br>" if m[:newline]
  next if s[:text].to_s.empty?
  t = CGI.escapeHTML(s[:text].dup.force_encoding("UTF-8"))
  t = "<b>#{t}</b>" if m[:bold]
  t = "<i>#{t}</i>" if m[:italic]
  t = "<u>#{t}</u>" if m[:underline]
  html << t
end
html << "</p>"
puts html

The repository’s bin/rtf_parse script is a fuller converter with fonts, colors, tables and images.

How to list the fonts and colors#

Ruby
doc.font_table.each { |font| puts font.name if font }
doc.color_table.each { |c| puts "rgb(#{c.red}, #{c.green}, #{c.blue})" if c && !c.use_default? }

How to read tables#

Ruby
doc.sections.each do |s|
  table = s[:modifiers][:table]
  next unless table
  table.rows.each do |row|
    puts row.cells.map { |cell| cell.sections.map { |cs| cs[:text] }.join }.join(" | ")
  end
end

Tips#