Skip to content

Commit 1b25c8c

Browse files
committed
feat(header): Add support for none-ANSI character set & code page
1 parent bd3e2b6 commit 1b25c8c

4 files changed

Lines changed: 36 additions & 11 deletions

File tree

src/header.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub struct Style {
3939
#[cfg_attr(feature = "jsbindings", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
4040
pub struct RtfHeader {
4141
pub character_set: CharacterSet,
42+
pub code_page: Option<u16>,
4243
pub font_table: FontTable,
4344
pub color_table: ColorTable,
4445
pub stylesheet: StyleSheet,
@@ -66,17 +67,18 @@ pub struct Color {
6667
pub enum CharacterSet {
6768
#[default]
6869
Ansi,
69-
Mac,
70-
Pc,
71-
Pca,
72-
Ansicpg(u16),
70+
Mac, // Apple Macintosh
71+
Pc, // IBM PC code page 437
72+
Pca, // IBM PC code page 850
7373
}
7474

7575
impl CharacterSet {
7676
pub fn from(token: &Token) -> Option<Self> {
7777
match token {
7878
Token::ControlSymbol((ControlWord::Ansi, _)) => Some(Self::Ansi),
79-
// TODO: implement the rest
79+
Token::ControlSymbol((ControlWord::Mac, _)) => Some(Self::Mac),
80+
Token::ControlSymbol((ControlWord::Pc, _)) => Some(Self::Pc),
81+
Token::ControlSymbol((ControlWord::Pca, _)) => Some(Self::Pca),
8082
_ => None,
8183
}
8284
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RTF parser for Text Editor
22
// This library supports RTF version 1.9.1
3-
// Specification is available here : https://dokumen.tips/documents/rtf-specification.html
3+
// Specification is available here : https://dokumen.tips/documents/rtf-specification.html and https://github.com/GoodNotes/tree-sitter-rtf/blob/main/specs/rtf-specs-1.9.1.pdf
44
// Explanations on specification here : https://www.oreilly.com/library/view/rtf-pocket-guide/9781449302047/ch01.html
55

66
#![allow(irrefutable_let_patterns)]

src/parser.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,15 @@ impl<'a> Parser<'a> {
397397
}
398398
// Check and consume token
399399
(token, _) => {
400-
if let Some(charset) = CharacterSet::from(token) {
401-
header.character_set = charset;
400+
match token {
401+
Token::ControlSymbol((ControlWord::AnsiCpg, code_page)) => {
402+
header.code_page = Some(code_page.get_value_as::<u16>()?);
403+
}
404+
_ => {
405+
if let Some(character_set) = CharacterSet::from(token) {
406+
header.character_set = character_set;
407+
}
408+
}
402409
}
403410
self.cursor += 1;
404411
}
@@ -497,12 +504,13 @@ pub mod tests {
497504

498505
#[test]
499506
fn parser_header() {
500-
let tokens = Lexer::scan(r#"{ \rtf1\ansi{\fonttbl\f0\fswiss Helvetica;}\f0\pard Voici du texte en {\b gras}.\par }"#).unwrap();
507+
let tokens = Lexer::scan(r#"{ \rtf1\ansi\ansicpg1252{\fonttbl\f0\fswiss Helvetica;}\f0\pard Voici du texte en {\b gras}.\par }"#).unwrap();
501508
let doc = Parser::new(tokens).parse().unwrap();
502509
assert_eq!(
503510
doc.header,
504511
RtfHeader {
505512
character_set: Ansi,
513+
code_page: Some(1252),
506514
font_table: FontTable::from([(
507515
0,
508516
Font {
@@ -562,6 +570,7 @@ pub mod tests {
562570
doc.header,
563571
RtfHeader {
564572
character_set: Ansi,
573+
code_page: Some(1252),
565574
font_table: FontTable::from([
566575
(
567576
0,

src/tokens.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,14 @@ impl Property {
9191
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
9292
pub enum ControlWord<'a> {
9393
Rtf,
94-
Ansi,
94+
95+
// Character Set
96+
Ansi, // default
97+
Mac, // Apple Macintosh
98+
Pc, // IBM PC code page 437
99+
Pca, // BM PC code page 850
100+
AnsiCpg, // ANSI code page used to perform the Unicode to ANSI conversion
101+
95102

96103
Unicode,
97104
UnicodeIgnoreCount,
@@ -187,7 +194,12 @@ impl<'a> ControlWord<'a> {
187194
#[rustfmt::skip]
188195
let control_word = match prefix {
189196
r"\rtf" => ControlWord::Rtf,
197+
// Character set
190198
r"\ansi" => ControlWord::Ansi,
199+
r"\mac" => ControlWord::Mac,
200+
r"\pc" => ControlWord::Pc,
201+
r"\pca" => ControlWord::Pca,
202+
r"\ansicpg" => ControlWord::AnsiCpg,
191203
// Unicode
192204
r"\u" => ControlWord::Unicode,
193205
r"\uc" => ControlWord::UnicodeIgnoreCount,
@@ -258,7 +270,9 @@ mod tests {
258270
#[test]
259271
fn control_word_from_input_test() {
260272
let input = r"\rtf1";
261-
assert_eq!(ControlWord::from(input).unwrap(), (ControlWord::Rtf, Property::Value(1)))
273+
assert_eq!(ControlWord::from(input).unwrap(), (ControlWord::Rtf, Property::Value(1)));
274+
let cpg_input = r"\ansicpg1252";
275+
assert_eq!(ControlWord::from(cpg_input).unwrap(), (ControlWord::AnsiCpg, Property::Value(1252)))
262276
}
263277

264278
#[test]

0 commit comments

Comments
 (0)