Expand description
This crate changes text between Apple’s classic Mac OS encodings and Unicode.
Apple wrote the mappings and publishes them as mapping files. The
generator in tools/generate-tables reads those files and writes the
tables in src/tables.rs. The decode and encode operations obey the WHATWG
Encoding Standard, sections 9.1 and
9.2. Thus this crate and a web browser give the same result for each
encoding in the standard.
use mac_encoding::Encoding;
// A resource type code goes through Mac OS Roman and comes back.
assert_eq!(Encoding::Roman.decode(b"CODE"), "CODE");
assert_eq!(Encoding::Roman.encode("CODE").unwrap(), b"CODE");
// The standard calls this encoding `macintosh`.
assert_eq!(Encoding::from_label("X-Mac-Roman"), Some(Encoding::Roman));§The encodings in the standard
The standard gives a name to only two of these encodings. Mac OS Roman is
macintosh and Mac OS Cyrillic is x-mac-cyrillic. The other 19
encodings have no name in the standard. Use Encoding::from_id for
them and Encoding::from_label for the other two.
In the standard, x-mac-cyrillic also has the label x-mac-ukrainian.
This agrees with Apple. The mapping file UKRAINE.TXT tells us that Mac
OS 9 put the Ukrainian characters into Mac OS Cyrillic. Thus this crate
has no Ukrainian encoding, because Apple supplies no mapping file for it.
§Two conditions that the standard does not include
Section 9.1 permits a decoder to answer an ASCII byte with the same
value. This is not correct for three of these encodings. Mac OS Symbol has
GREEK CAPITAL LETTER ALPHA at byte 0x41. Mac OS Dingbats and Mac OS
Keyboard also give other characters to many bytes in that range. Thus the
decoder always uses the table. For the other encodings, the table gives
the same result as the rule in the standard.
Section 9 also has this rule: one byte gives one code point or none. Apple’s tables do not obey that rule. Mac OS Thai gives a character and its position as two code points. Mac OS Devanagari, Gujarati, and Gurmukhi give a two-byte code to some ligatures. The decoder and the encoder both use the longest match first. Thus these mappings are correct in the two directions.
§Encodings that cannot encode a byte again correctly
Mac OS Arabic, Farsi, and Hebrew give a direction to each mapping. Thus
more than one byte can have the same code point. For example, byte 0x2B
and byte 0xAB are both PLUS SIGN. Only the direction is different. The
decoder removes the direction and the encoder gives the lowest byte. Thus
a byte from the right-to-left group comes back as its left-to-right
equivalent.
Mac OS Keyboard has one such condition for a different reason. Byte 0x09
and byte 0x61 both decode to U+2423 OPEN BOX. Apple’s comment for that
mapping says “duplicates mapping for 0x61, hence no round-trip”.
Encoding::encode_is_lossy tells you about all four encodings.
Encoding::is_directional tells you about the three with directions. To
encode text and then to decode it is always correct. Only the opposite
sequence can give a different byte.
§Control characters in Mac OS Keyboard
Apple’s mapping files do not include the bytes 0x00 to 0x1F and the
byte 0x7F. For almost all encodings, each of these bytes gives the
control character with the same value. Mac OS Keyboard is different. It
gives key symbols to 22 of these bytes. For example, byte 0x02 is U+21E5
LEFTWARDS ARROW TO BAR.
That font has no byte for the control character itself. Thus
Encoding::encode gives an error for those 22 control characters, and
Encoding::encode_html writes a character reference.
§This crate does not need std
The crate is no_std and uses alloc for String and Vec. It has
no features and no dependencies.
Modules§
- macroman
- Mac OS Roman, for classic Mac OS resource text.
Structs§
- Decode
Error - The encoding has no character for this byte.
- Encode
Error - The encoding has no byte for this character.
Enums§
- Encoding
- The encodings. The generator writes this list and the tables together, so the two always agree.
Constants§
- ALL
- All the encodings in this crate, in Apple’s sequence.