use super::error::Result;
use super::parser::Record;
#[cfg_attr(alef, alef(skip))]
#[derive(Debug, Default)]
pub struct HwpDocument {
pub sections: Vec<Section>,
pub char_shapes: Vec<CharShape>,
pub images: Vec<HwpImage>,
}
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
pub struct Section {
pub paragraphs: Vec<Paragraph>,
}
#[cfg_attr(alef, alef(skip))]
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
pub struct Paragraph {
pub text: Option<ParaText>,
pub outline_level: u8,
pub char_shape_runs: Vec<(u32, u16)>,
}
#[cfg_attr(alef, alef(skip))]
#[derive(Debug, Clone, Copy, Default)]
pub struct CharShape {
pub bold: bool,
pub italic: bool,
pub underline: bool,
}
#[cfg_attr(alef, alef(skip))]
#[derive(Debug, Clone, Default)]
pub struct HwpImage {
pub name: String,
pub data: Vec<u8>,
}
#[cfg_attr(alef, alef(skip))]
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct ParaText {
pub content: String,
}
impl ParaText {
pub(crate) fn from_record(record: &Record) -> Result<Self> {
let mut reader = record.data_reader();
let mut chars: Vec<u16> = Vec::with_capacity(record.data.len() / 2);
while reader.remaining() >= 2 {
chars.push(reader.read_u16()?);
}
let mut content = String::with_capacity(chars.len());
let mut i = 0;
while i < chars.len() {
let ch = chars[i];
match ch {
0x0000 => {}
0x0001..=0x0008 => {
i += 7;
}
0x0009 => {
content.push('\t');
i += 7;
}
0x000A => content.push('\n'),
0x000D => {}
0x000B..=0x000C | 0x000E..=0x001F => {
i += 7;
}
0xF020..=0xF07F => {}
_ => {
if let Some(c) = char::from_u32(ch as u32) {
content.push(c);
}
}
}
i += 1;
}
Ok(Self { content })
}
}