Skip to content

Commit f62c620

Browse files
committed
version 0.2.0
1 parent 68f6e41 commit f62c620

File tree

13 files changed

+251
-299
lines changed

13 files changed

+251
-299
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "hwpers"
3-
version = "0.1.0"
3+
version = "0.2.0"
44
edition = "2021"
55
authors = ["HWP Parser Contributors"]
66
description = "A Rust library for parsing Korean Hangul Word Processor (HWP) files with full layout rendering support"

examples/create_document.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@ use hwpers::HwpWriter;
22

33
fn main() -> Result<(), Box<dyn std::error::Error>> {
44
println!("Creating new HWP document...\n");
5-
5+
66
// Create a new HWP writer
77
let mut writer = HwpWriter::new();
8-
8+
99
// Add content
1010
writer.add_paragraph("안녕하세요! 이것은 hwpers 라이브러리로 만든 HWP 문서입니다.")?;
1111
writer.add_paragraph("")?; // Empty paragraph for spacing
1212
writer.add_paragraph("This document was created using the hwpers Rust library.")?;
1313
writer.add_paragraph("It should open correctly in Hangul word processor.")?;
14-
14+
1515
// Save to file
1616
writer.save_to_file("example_document.hwp")?;
17-
17+
1818
println!("✅ Created example_document.hwp");
1919
println!("This file can be opened in Hangul word processor.");
20-
20+
2121
Ok(())
22-
}
22+
}

examples/verify_roundtrip.rs

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,68 +3,82 @@ use std::fs;
33

44
fn main() -> Result<(), Box<dyn std::error::Error>> {
55
println!("=== Round-trip Verification ===\n");
6-
6+
77
// 1. Read original file
88
let original_path = "test-files/test_document.hwp";
99
let original_bytes = fs::read(original_path)?;
1010
println!("Original file size: {} bytes", original_bytes.len());
11-
11+
1212
let original_doc = HwpReader::from_file(original_path)?;
1313
let original_text = original_doc.extract_text();
1414
println!("Original text length: {} characters", original_text.len());
1515
println!("Original text hash: {:x}", md5::compute(&original_text));
16-
println!("First 200 chars: {:?}", &original_text.chars().take(200).collect::<String>());
17-
16+
println!(
17+
"First 200 chars: {:?}",
18+
&original_text.chars().take(200).collect::<String>()
19+
);
20+
1821
// 2. Convert to Writer and save
1922
let writer = HwpWriter::from_document(original_doc);
2023
let roundtrip_path = "verify_roundtrip.hwp";
2124
writer.save_to_file(roundtrip_path)?;
22-
25+
2326
let roundtrip_bytes = fs::read(roundtrip_path)?;
2427
println!("\nRoundtrip file size: {} bytes", roundtrip_bytes.len());
25-
28+
2629
// 3. Read back the roundtrip file
2730
let roundtrip_doc = HwpReader::from_file(roundtrip_path)?;
2831
let roundtrip_text = roundtrip_doc.extract_text();
2932
println!("Roundtrip text length: {} characters", roundtrip_text.len());
3033
println!("Roundtrip text hash: {:x}", md5::compute(&roundtrip_text));
31-
println!("First 200 chars: {:?}", &roundtrip_text.chars().take(200).collect::<String>());
32-
34+
println!(
35+
"First 200 chars: {:?}",
36+
&roundtrip_text.chars().take(200).collect::<String>()
37+
);
38+
3339
// 4. Compare character by character
3440
println!("\n=== Comparison ===");
3541
if original_text == roundtrip_text {
3642
println!("✅ PERFECT MATCH! Every single character is identical!");
37-
43+
3844
// Additional verification
3945
let orig_chars: Vec<char> = original_text.chars().collect();
4046
let round_chars: Vec<char> = roundtrip_text.chars().collect();
41-
42-
println!("Character count: {} vs {}", orig_chars.len(), round_chars.len());
43-
47+
48+
println!(
49+
"Character count: {} vs {}",
50+
orig_chars.len(),
51+
round_chars.len()
52+
);
53+
4454
// Check some random positions
4555
let positions = [0, 100, 500, 1000, 5000];
4656
for &pos in &positions {
4757
if pos < orig_chars.len() {
48-
println!("Position {}: '{}' vs '{}'",
49-
pos, orig_chars[pos], round_chars[pos]);
58+
println!(
59+
"Position {}: '{}' vs '{}'",
60+
pos, orig_chars[pos], round_chars[pos]
61+
);
5062
}
5163
}
5264
} else {
5365
println!("❌ Text differs!");
54-
66+
5567
// Find first difference
5668
let orig_chars: Vec<char> = original_text.chars().collect();
5769
let round_chars: Vec<char> = roundtrip_text.chars().collect();
58-
70+
5971
for i in 0..orig_chars.len().min(round_chars.len()) {
6072
if orig_chars[i] != round_chars[i] {
61-
println!("First difference at position {}: '{}' vs '{}'",
62-
i, orig_chars[i], round_chars[i]);
73+
println!(
74+
"First difference at position {}: '{}' vs '{}'",
75+
i, orig_chars[i], round_chars[i]
76+
);
6377
break;
6478
}
6579
}
6680
}
67-
81+
6882
Ok(())
6983
}
7084

@@ -77,4 +91,4 @@ mod md5 {
7791
data.hash(&mut hasher);
7892
hasher.finish() as u128
7993
}
80-
}
94+
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use std::path::Path;
1111

1212
pub use crate::error::{HwpError, Result};
1313
pub use crate::model::HwpDocument;
14-
pub use crate::writer::HwpWriter;
1514
use crate::parser::{body_text::BodyTextParser, doc_info::DocInfoParser, header::FileHeader};
1615
use crate::reader::CfbReader;
16+
pub use crate::writer::HwpWriter;
1717

1818
pub struct HwpReader;
1919

src/model/border_fill.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,9 @@ impl BorderFill {
135135
/// Create a new default BorderFill for writing
136136
pub fn new_default() -> Self {
137137
let default_border = BorderLine {
138-
line_type: 0, // No border
138+
line_type: 0, // No border
139139
thickness: 0,
140-
color: 0x000000, // Black
140+
color: 0x000000, // Black
141141
};
142142

143143
Self {

src/model/char_shape.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,16 @@ impl CharShape {
105105
/// Create a new default CharShape for writing
106106
pub fn new_default() -> Self {
107107
Self {
108-
face_name_ids: [0; 7], // Use first font (index 0)
109-
ratios: [100; 7], // 100% ratio
110-
char_spaces: [0; 7], // No character spacing
108+
face_name_ids: [0; 7], // Use first font (index 0)
109+
ratios: [100; 7], // 100% ratio
110+
char_spaces: [0; 7], // No character spacing
111111
relative_sizes: [100; 7], // 100% relative size
112-
char_offsets: [0; 7], // No offset
113-
base_size: 1200, // 12pt (100 units per point)
114-
properties: 0, // No bold, italic, etc.
112+
char_offsets: [0; 7], // No offset
113+
base_size: 1200, // 12pt (100 units per point)
114+
properties: 0, // No bold, italic, etc.
115115
shadow_gap_x: 0,
116116
shadow_gap_y: 0,
117-
text_color: 0x000000, // Black text
117+
text_color: 0x000000, // Black text
118118
underline_color: 0x000000,
119119
shade_color: 0xFFFFFF, // White shade
120120
shadow_color: 0x808080, // Gray shadow

src/model/para_shape.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ impl ParaShape {
7474
/// Create a new default ParaShape for writing
7575
pub fn new_default() -> Self {
7676
Self {
77-
properties1: 0x04, // Left alignment (bits 2-4 = 001)
77+
properties1: 0x04, // Left alignment (bits 2-4 = 001)
7878
left_margin: 0,
7979
right_margin: 0,
8080
indent: 0,
8181
top_para_space: 0,
8282
bottom_para_space: 0,
83-
line_space: 160, // 160% line spacing
83+
line_space: 160, // 160% line spacing
8484
tab_def_id: 0,
8585
numbering_id: 0,
8686
border_fill_id: 0,
@@ -90,7 +90,7 @@ impl ParaShape {
9090
border_bottom_space: 0,
9191
properties2: 0,
9292
properties3: 0,
93-
line_space_type: 0, // Percentage
93+
line_space_type: 0, // Percentage
9494
}
9595
}
96-
}
96+
}

src/parser/header.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,11 @@ impl FileHeader {
105105
pub fn new_default() -> Self {
106106
let mut signature = [0u8; 32];
107107
signature[..17].copy_from_slice(HWP_SIGNATURE);
108-
108+
109109
Self {
110110
signature,
111111
version: 0x05050114, // HWP 5.0.5.1 version
112-
flags: 0x01, // Enable compression
112+
flags: 0x01, // Enable compression
113113
reserved: [0u8; 216],
114114
}
115115
}

src/writer/mod.rs

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,16 @@ pub mod serializer;
22

33
use crate::error::{HwpError, Result};
44
use crate::model::{
5-
HwpDocument,
6-
document::DocumentProperties,
7-
paragraph::{Section, Paragraph, ParaText},
5+
border_fill::BorderFill,
86
char_shape::{CharShape, FaceName},
7+
document::DocumentProperties,
98
para_shape::ParaShape,
9+
paragraph::{ParaText, Paragraph, Section},
1010
style::Style,
11-
border_fill::BorderFill,
1211
tab_def::TabDef,
13-
14-
};
15-
use crate::parser::{
16-
header::FileHeader,
17-
doc_info::DocInfo,
18-
body_text::BodyText,
12+
HwpDocument,
1913
};
14+
use crate::parser::{body_text::BodyText, doc_info::DocInfo, header::FileHeader};
2015
use std::path::Path;
2116

2217
pub struct HwpWriter {
@@ -30,7 +25,7 @@ impl HwpWriter {
3025
let header = Self::create_default_header();
3126
let doc_info = Self::create_default_doc_info();
3227
let body_texts = vec![Self::create_default_body_text()];
33-
28+
3429
Self {
3530
document: HwpDocument {
3631
header,
@@ -81,8 +76,7 @@ impl HwpWriter {
8176
/// Save to file
8277
pub fn save_to_file<P: AsRef<Path>>(&self, path: P) -> Result<()> {
8378
let bytes = self.to_bytes()?;
84-
std::fs::write(path, bytes)
85-
.map_err(|e| HwpError::Io(e))?;
79+
std::fs::write(path, bytes).map_err(HwpError::Io)?;
8680
Ok(())
8781
}
8882

@@ -95,24 +89,16 @@ impl HwpWriter {
9589
fn create_default_doc_info() -> DocInfo {
9690
DocInfo {
9791
properties: Some(DocumentProperties::default()),
98-
face_names: vec![
99-
FaceName::new_default("맑은 고딕".to_string()),
100-
],
92+
face_names: vec![FaceName::new_default("맑은 고딕".to_string())],
10193
char_shapes: vec![
10294
CharShape::new_default(), // Default 12pt font
10395
],
10496
para_shapes: vec![
10597
ParaShape::new_default(), // Default left-aligned paragraph
10698
],
107-
styles: vec![
108-
Style::new_default(),
109-
],
110-
border_fills: vec![
111-
BorderFill::new_default(),
112-
],
113-
tab_defs: vec![
114-
TabDef::new_default(),
115-
],
99+
styles: vec![Style::new_default()],
100+
border_fills: vec![BorderFill::new_default()],
101+
tab_defs: vec![TabDef::new_default()],
116102
numberings: Vec::new(),
117103
bullets: Vec::new(),
118104
bin_data: Vec::new(),
@@ -151,4 +137,4 @@ impl Default for HwpWriter {
151137
fn default() -> Self {
152138
Self::new()
153139
}
154-
}
140+
}

0 commit comments

Comments
 (0)