All formats

Cabriolet

LanguageRuby (2.7+)
LicenseBSD-3-Clause
Repositorygithub.com/omnizip/cabriolet
DocumentationREADME, gem page
Depends onbindata, thor (no C extensions)
Read / writeyes / yes, unprotected LIT files only (no DES-encrypted DRM)

Cabriolet implements Microsoft’s archive and compression formats in pure Ruby: CAB, CHM, SZDD, KWAJ, HLP, LIT and OAB. For LIT it parses the container, decompresses the LZX sections and restores the original file names from the manifest. It also has a command line tool.

Limitations: DRM-protected (DES-encrypted) books raise an error. Extracted HTML documents are the raw stored streams, which in LIT use a binary tag encoding, so you may still need calibre or ConvertLIT to get readable HTML. The project is young (first release in November 2025) and parts of its documentation describe methods that don’t exist; the examples below follow the source code of version 0.2.

Installation#

Shell
gem install cabriolet

Or in a Gemfile:

Ruby
gem "cabriolet"

Basic usage: extract a LIT book#

Ruby
require "cabriolet"

decompressor = Cabriolet::LIT::Decompressor.new
begin
  lit = decompressor.open("book.lit")   # raises NotImplementedError for DRM books
rescue NotImplementedError => e
  abort "can't open: #{e.message}"
end

count = decompressor.extract_all(lit, "book/")   # uses original names from the manifest
puts "extracted #{count} files"

The same from the command line:

Shell
cabriolet lit-info book.lit
cabriolet lit-extract book.lit book/

How to list the files in a LIT book#

Ruby
require "cabriolet"

decompressor = Cabriolet::LIT::Decompressor.new
lit = decompressor.open("book.lit")
decompressor.list_files(lit).each do |f|
  puts "#{f[:internal_name]}  #{f[:size]} bytes"
end

How to read the manifest#

The manifest maps internal names to original file names and MIME types:

Ruby
lit = Cabriolet::LIT::Decompressor.new.open("book.lit")
if lit.manifest
  lit.manifest.html_files.each { |m| puts "#{m.original_name} (#{m.content_type})" }
  lit.manifest.image_files.each { |m| puts m.original_name }
end
puts "language id: 0x%04x" % lit.language_id

How to check if a LIT file has DRM#

open raises NotImplementedError for encrypted files:

Ruby
def lit_drm?(path)
  Cabriolet::LIT::Decompressor.new.open(path)
  false
rescue NotImplementedError
  true
end

How to create a LIT file#

Ruby
require "cabriolet"

compressor = Cabriolet::LIT::Compressor.new
compressor.add_file("chapter1.html", "/chapter1.html")
compressor.add_file("cover.jpg", "/cover.jpg")
compressor.generate("book.lit")

This writes the LIT container (directory, LZX sections, manifest). Cabriolet stores the files as given: it doesn’t produce the binary tag encoding of HTML or the /meta package file that Microsoft Reader uses, so test the output with the reader you target.