Encoding::Emacs
Encoding::Emacs
Auto-generated character encodings from Emacs MULE definitions. Provides 80+ legacy character encodings for Raku, including ISO-8859, Windows codepages, DOS codepages, KOI8, EBCDIC, and more.
Installation
zef install Encoding::EmacsOr from source:
git clone https://github.com/winfred-raj/encoding-emacs.git
cd encoding-emacs
zef install .Quick Start
#!/usr/bin/env raku
use Encoding::Emacs::Full::Cp850;
# Decode CP850 bytes (DOS encoding with box-drawing chars)
my $bytes = Buf.new(0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x9D); # "Hello Γ"
my $decoder = Encoding::Emacs::Full::Cp850.decoder;
my $text = $decoder.consume($bytes);
say $text; # Output: Hello Γ
# Encode Unicode string to CP850
my $encoder = Encoding::Emacs::Full::Cp850.encoder;
my $encoded = $encoder.encode-chars("GrΓΌΓ Gott");
say $encoded; # Output: Buf:0x<47 72 81 E1 20 47 6F 74 74>Supported Encodings
ISO-8859 Series (Latin)
ISO-8859-2 (Central European)
ISO-8859-3 (South European)
ISO-8859-4 (North European)
ISO-8859-5 (Cyrillic)
ISO-8859-6 (Arabic)
ISO-8859-7 (Greek)
ISO-8859-8 (Hebrew)
ISO-8859-9 (Turkish)
ISO-8859-14 (Celtic)
ISO-8859-15 (Latin-9 with Euro sign)
Windows Codepages
CP1250 (Central European)
CP1251 (Cyrillic)
CP1252 (Western European)
CP1253 (Greek)
CP1254 (Turkish)
CP1255 (Hebrew)
CP1256 (Arabic)
CP1257 (Baltic)
CP1258 (Vietnamese)
DOS Codepages
CP437 (Original IBM PC)
CP850 (Western European)
CP852 (Central European)
CP855, CP857, CP860-865 (Various regions)
CP866 (Russian)
KOI8 Variants
KOI8-R (Russian)
KOI8-U (Ukrainian)
KOI8-T (Tajik)
Other Legacy Encodings
Mac Roman
HP Roman8
VISCII (Vietnamese)
IBM EBCDIC variants
And 50+ more!
Usage Examples
Decode Legacy Files
use Encoding::Emacs::Full::Iso_8859_5; # Cyrillic
my $bytes = slurp("old-file.txt", :bin);
my $decoder = Encoding::Emacs::Full::Iso_8859_5.decoder;
my $text = $decoder.consume($bytes);
say $text; # Readable Russian textEncode for Legacy Systems
use Encoding::Emacs::Full::Windows_1252;
my $unicode-text = "CafΓ© rΓ©sumΓ©";
my $encoder = Encoding::Emacs::Full::Windows_1252.encoder;
my $bytes = $encoder.encode-chars($unicode-text);
spurt("output.txt", $bytes);Round-Trip Conversion
use Encoding::Emacs::Full::Cp866; # Russian DOS
my $original = "ΠΡΠΈΠ²Π΅Ρ ΠΌΠΈΡ!";
my $encoder = Encoding::Emacs::Full::Cp866.encoder;
my $decoder = Encoding::Emacs::Full::Cp866.decoder;
my $encoded = $encoder.encode-chars($original);
my $decoded = $decoder.consume($encoded);
say $decoded eq $original; # TrueEncoding::Registry Integration
Encoding::Emacs::Registry bridges these encodings into Raku's built-in
Encoding::Registry. Just use it once and all supported single-byte
encodings are registered by name (and alias):
use Encoding::Emacs::Registry;
# Look encodings up by name through the standard registry
my $bytes = Buf.new(0x41, 0xB5);
say emacs-decode($bytes, "cp850"); # AΓ
say emacs-encode("AΓ", "cp850"); # Buf:0x<41 B5>
# Or go through Encoding::Registry directly
my $dec = Encoding::Registry.find("cp850").decoder;
$dec.add-bytes($bytes);
say $dec.consume-all-chars; # AΓemacs-decode / emacs-encode are convenience wrappers because Raku's
Buf.decode does not route through Encoding::Registry; use them when you
want a one-call decode/encode by encoding name.
How It Works
This module parses Emacs' MULE (Multilingual Environment) charset definitions and mapping tables to automatically generate Raku encoding classes. Each encoding:
Lazy loads mapping tables on first use
Caches mappings for performance
Uses hash-based O(1) lookups for encode/decode
Implements Raku's Encoding::Encoder and Encoding::Decoder roles
Performance
Mapping load: O(n) - done once per encoding, then cached
Decode: O(m) - where m = bytes in input
Encode: O(k) - where k = characters in input
Memory: ~1-2 KB per loaded encoding
Architecture
Encoding::Emacs/
βββ Parser.rakumod # Parses Emacs Lisp charset definitions
βββ Generator.rakumod # Generates Raku encoding classes
βββ MappingTable.rakumod # Runtime mapping table loader
βββ Full/ # 81 generated encoding classes
βββ Iso_8859_5.rakumod
βββ Cp850.rakumod
βββ Windows_1252.rakumod
βββ ...Development
Generate Encodings
raku bin/generate-encodings.raku emacs-src/mule-conf.el lib/Encoding/Emacs/FullRun Tests
raku -I lib t/01-parser.rakutest # Parser tests
raku -I lib t/02-generator.rakutest # Generator tests
raku -I lib t/03-mapping-table.rakutest # Mapping loader tests
raku -I lib t/04-encoding-decoding.rakutest # Encode/decode tests
raku -I lib t/05-phase3-encode-decode.rakutest # Round-trip tests
raku -I lib t/06-cp850-encoding.rakutest # CP850 specific testsAll 52 tests should pass.
Status
β Phase 1: Parser - Complete
β Phase 2: Code Generator - Complete
β Phase 3: Mapping Tables - Complete
β Phase 4: Encoding::Registry integration - Complete
Limitations
Currently supports single-byte encodings only
Multi-byte encodings (UTF-16, Shift-JIS, EUC, Big5, etc.) are in the mapping files but require additional implementation
Contributing
Contributions welcome! Please:
Fork the repository
Create a feature branch
Add tests for new functionality
Ensure all tests pass
Submit a pull request
License
Artistic License 2.0 (same as Raku)
Author
Winfred Raj
See Also
Acknowledgments
Built using Emacs' comprehensive MULE (Multilingual Environment) charset definitions and mapping tables, originally created by the GNU Emacs team.