Cabriolet
| Language | Ruby (2.7+) |
|---|---|
| License | BSD-3-Clause |
| Repository | github.com/omnizip/cabriolet |
| Documentation | README, gem page |
| Depends on | bindata, thor (no C extensions) |
| Read / write | yes / 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#
gem install cabriolet
Or in a Gemfile:
gem "cabriolet"
Basic usage: extract a LIT book#
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:
cabriolet lit-info book.lit
cabriolet lit-extract book.lit book/
How to list the files in a LIT book#
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:
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:
def lit_drm?(path)
Cabriolet::LIT::Decompressor.new.open(path)
false
rescue NotImplementedError
true
end
How to create a LIT file#
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.