Support start chars (#51)
* feat: suport start char for writer * support start char and add option to indent start * fix:lint error * fix: lintmain
parent
4378de2ecc
commit
6f54e5e493
|
@ -6,22 +6,25 @@ pub fn main() -> Result<(), DocxError> {
|
||||||
let path = std::path::Path::new("./output/indent.docx");
|
let path = std::path::Path::new("./output/indent.docx");
|
||||||
let file = std::fs::File::create(&path).unwrap();
|
let file = std::fs::File::create(&path).unwrap();
|
||||||
Docx::new()
|
Docx::new()
|
||||||
.add_paragraph(
|
|
||||||
Paragraph::new()
|
|
||||||
.add_run(Run::new().add_text(DUMMY))
|
|
||||||
.indent(840, None, None),
|
|
||||||
)
|
|
||||||
.add_paragraph(Paragraph::new())
|
|
||||||
.add_paragraph(Paragraph::new().add_run(Run::new().add_text(DUMMY)).indent(
|
.add_paragraph(Paragraph::new().add_run(Run::new().add_text(DUMMY)).indent(
|
||||||
840,
|
Some(840),
|
||||||
Some(SpecialIndentType::FirstLine(720)),
|
None,
|
||||||
|
None,
|
||||||
None,
|
None,
|
||||||
))
|
))
|
||||||
.add_paragraph(Paragraph::new())
|
.add_paragraph(Paragraph::new())
|
||||||
.add_paragraph(Paragraph::new().add_run(Run::new().add_text(DUMMY)).indent(
|
.add_paragraph(Paragraph::new().add_run(Run::new().add_text(DUMMY)).indent(
|
||||||
1560,
|
Some(840),
|
||||||
|
Some(SpecialIndentType::FirstLine(720)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
))
|
||||||
|
.add_paragraph(Paragraph::new())
|
||||||
|
.add_paragraph(Paragraph::new().add_run(Run::new().add_text(DUMMY)).indent(
|
||||||
|
Some(1560),
|
||||||
Some(SpecialIndentType::Hanging(720)),
|
Some(SpecialIndentType::Hanging(720)),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
))
|
))
|
||||||
.build()
|
.build()
|
||||||
.pack(file)?;
|
.pack(file)?;
|
||||||
|
|
|
@ -18,7 +18,12 @@ pub fn main() -> Result<(), DocxError> {
|
||||||
LevelText::new("Section %1."),
|
LevelText::new("Section %1."),
|
||||||
LevelJc::new("left"),
|
LevelJc::new("left"),
|
||||||
)
|
)
|
||||||
.indent(1620, Some(SpecialIndentType::Hanging(320)), None),
|
.indent(
|
||||||
|
Some(1620),
|
||||||
|
Some(SpecialIndentType::Hanging(320)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.add_numbering(Numbering::new(2, 2))
|
.add_numbering(Numbering::new(2, 2))
|
||||||
|
|
|
@ -7,15 +7,22 @@ use crate::xml_builder::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Indent {
|
pub struct Indent {
|
||||||
start: i32,
|
start: Option<i32>,
|
||||||
end: Option<i32>,
|
end: Option<i32>,
|
||||||
special_indent: Option<SpecialIndentType>,
|
special_indent: Option<SpecialIndentType>,
|
||||||
|
start_chars: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Indent {
|
impl Indent {
|
||||||
pub fn new(start: i32, special_indent: Option<SpecialIndentType>, end: Option<i32>) -> Indent {
|
pub fn new(
|
||||||
|
start: Option<i32>,
|
||||||
|
special_indent: Option<SpecialIndentType>,
|
||||||
|
end: Option<i32>,
|
||||||
|
start_chars: Option<i32>,
|
||||||
|
) -> Indent {
|
||||||
Indent {
|
Indent {
|
||||||
start,
|
start,
|
||||||
|
start_chars,
|
||||||
end,
|
end,
|
||||||
special_indent,
|
special_indent,
|
||||||
}
|
}
|
||||||
|
@ -34,6 +41,7 @@ impl BuildXML for Indent {
|
||||||
self.start,
|
self.start,
|
||||||
self.special_indent,
|
self.special_indent,
|
||||||
self.end.unwrap_or_default(),
|
self.end.unwrap_or_default(),
|
||||||
|
self.start_chars,
|
||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
@ -46,6 +54,7 @@ impl Serialize for Indent {
|
||||||
{
|
{
|
||||||
let mut t = serializer.serialize_struct("Indent", 3)?;
|
let mut t = serializer.serialize_struct("Indent", 3)?;
|
||||||
t.serialize_field("start", &self.start)?;
|
t.serialize_field("start", &self.start)?;
|
||||||
|
t.serialize_field("startChars", &self.start_chars)?;
|
||||||
t.serialize_field("end", &self.end)?;
|
t.serialize_field("end", &self.end)?;
|
||||||
t.serialize_field("specialIndent", &self.special_indent)?;
|
t.serialize_field("specialIndent", &self.special_indent)?;
|
||||||
t.end()
|
t.end()
|
||||||
|
@ -62,7 +71,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_left() {
|
fn test_left() {
|
||||||
let b = Indent::new(20, None, None).build();
|
let b = Indent::new(Some(20), None, None, None).build();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
str::from_utf8(&b).unwrap(),
|
str::from_utf8(&b).unwrap(),
|
||||||
r#"<w:ind w:left="20" w:right="0" />"#
|
r#"<w:ind w:left="20" w:right="0" />"#
|
||||||
|
@ -71,7 +80,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_first_line() {
|
fn test_first_line() {
|
||||||
let b = Indent::new(20, Some(SpecialIndentType::FirstLine(40)), None).build();
|
let b = Indent::new(Some(20), Some(SpecialIndentType::FirstLine(40)), None, None).build();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
str::from_utf8(&b).unwrap(),
|
str::from_utf8(&b).unwrap(),
|
||||||
r#"<w:ind w:left="20" w:right="0" w:firstLine="40" />"#
|
r#"<w:ind w:left="20" w:right="0" w:firstLine="40" />"#
|
||||||
|
@ -80,7 +89,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_hanging() {
|
fn test_hanging() {
|
||||||
let b = Indent::new(20, Some(SpecialIndentType::Hanging(50)), None).build();
|
let b = Indent::new(Some(20), Some(SpecialIndentType::Hanging(50)), None, None).build();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
str::from_utf8(&b).unwrap(),
|
str::from_utf8(&b).unwrap(),
|
||||||
r#"<w:ind w:left="20" w:right="0" w:hanging="50" />"#
|
r#"<w:ind w:left="20" w:right="0" w:hanging="50" />"#
|
||||||
|
|
|
@ -37,11 +37,14 @@ impl Level {
|
||||||
|
|
||||||
pub fn indent(
|
pub fn indent(
|
||||||
mut self,
|
mut self,
|
||||||
left: i32,
|
left: Option<i32>,
|
||||||
special_indent: Option<SpecialIndentType>,
|
special_indent: Option<SpecialIndentType>,
|
||||||
end: Option<i32>,
|
end: Option<i32>,
|
||||||
|
start_chars: Option<i32>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self.paragraph_property = self.paragraph_property.indent(left, special_indent, end);
|
self.paragraph_property =
|
||||||
|
self.paragraph_property
|
||||||
|
.indent(left, special_indent, end, start_chars);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +101,7 @@ mod tests {
|
||||||
LevelText::new("%4."),
|
LevelText::new("%4."),
|
||||||
LevelJc::new("left"),
|
LevelJc::new("left"),
|
||||||
)
|
)
|
||||||
.indent(320, Some(SpecialIndentType::Hanging(200)), None)
|
.indent(Some(320), Some(SpecialIndentType::Hanging(200)), None, None)
|
||||||
.build();
|
.build();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
str::from_utf8(&b).unwrap(),
|
str::from_utf8(&b).unwrap(),
|
||||||
|
|
|
@ -163,11 +163,12 @@ impl Paragraph {
|
||||||
|
|
||||||
pub fn indent(
|
pub fn indent(
|
||||||
mut self,
|
mut self,
|
||||||
left: i32,
|
left: Option<i32>,
|
||||||
special_indent: Option<SpecialIndentType>,
|
special_indent: Option<SpecialIndentType>,
|
||||||
end: Option<i32>,
|
end: Option<i32>,
|
||||||
|
start_chars: Option<i32>,
|
||||||
) -> Paragraph {
|
) -> Paragraph {
|
||||||
self.property = self.property.indent(left, special_indent, end);
|
self.property = self.property.indent(left, special_indent, end, start_chars);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,11 +50,12 @@ impl ParagraphProperty {
|
||||||
|
|
||||||
pub fn indent(
|
pub fn indent(
|
||||||
mut self,
|
mut self,
|
||||||
left: i32,
|
left: Option<i32>,
|
||||||
special_indent: Option<SpecialIndentType>,
|
special_indent: Option<SpecialIndentType>,
|
||||||
end: Option<i32>,
|
end: Option<i32>,
|
||||||
|
start_chars: Option<i32>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self.indent = Some(Indent::new(left, special_indent, end));
|
self.indent = Some(Indent::new(left, special_indent, end, start_chars));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_indent() {
|
fn test_indent() {
|
||||||
let c = ParagraphProperty::new();
|
let c = ParagraphProperty::new();
|
||||||
let b = c.indent(20, None, None).build();
|
let b = c.indent(Some(20), None, None, None).build();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
str::from_utf8(&b).unwrap(),
|
str::from_utf8(&b).unwrap(),
|
||||||
r#"<w:pPr><w:pStyle w:val="Normal" /><w:rPr /><w:ind w:left="20" w:right="0" /></w:pPr>"#
|
r#"<w:pPr><w:pStyle w:val="Normal" /><w:rPr /><w:ind w:left="20" w:right="0" /></w:pPr>"#
|
||||||
|
@ -119,10 +120,10 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_indent_json() {
|
fn test_indent_json() {
|
||||||
let c = ParagraphProperty::new();
|
let c = ParagraphProperty::new();
|
||||||
let b = c.indent(20, Some(SpecialIndentType::FirstLine(10)), None);
|
let b = c.indent(Some(20), Some(SpecialIndentType::FirstLine(10)), None, None);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
serde_json::to_string(&b).unwrap(),
|
serde_json::to_string(&b).unwrap(),
|
||||||
r#"{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null},"style":"Normal","numberingProperty":null,"alignment":null,"indent":{"start":20,"end":null,"specialIndent":{"type":"firstLine","val":10}}}"#
|
r#"{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null},"style":"Normal","numberingProperty":null,"alignment":null,"indent":{"start":20,"startChars":null,"end":null,"specialIndent":{"type":"firstLine","val":10}}}"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,11 +89,14 @@ impl Style {
|
||||||
|
|
||||||
pub fn indent(
|
pub fn indent(
|
||||||
mut self,
|
mut self,
|
||||||
left: i32,
|
left: Option<i32>,
|
||||||
special_indent: Option<SpecialIndentType>,
|
special_indent: Option<SpecialIndentType>,
|
||||||
end: Option<i32>,
|
end: Option<i32>,
|
||||||
|
start_chars: Option<i32>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self.paragraph_property = self.paragraph_property.indent(left, special_indent, end);
|
self.paragraph_property =
|
||||||
|
self.paragraph_property
|
||||||
|
.indent(left, special_indent, end, start_chars);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ fn create_default_numbering() -> AbstractNumbering {
|
||||||
LevelText::new("%1."),
|
LevelText::new("%1."),
|
||||||
LevelJc::new("left"),
|
LevelJc::new("left"),
|
||||||
)
|
)
|
||||||
.indent(420, Some(SpecialIndentType::Hanging(420)), None),
|
.indent(Some(420), Some(SpecialIndentType::Hanging(420)), None, None),
|
||||||
)
|
)
|
||||||
.add_level(
|
.add_level(
|
||||||
Level::new(
|
Level::new(
|
||||||
|
@ -72,7 +72,7 @@ fn create_default_numbering() -> AbstractNumbering {
|
||||||
LevelText::new("(%2)"),
|
LevelText::new("(%2)"),
|
||||||
LevelJc::new("left"),
|
LevelJc::new("left"),
|
||||||
)
|
)
|
||||||
.indent(840, Some(SpecialIndentType::Hanging(420)), None),
|
.indent(Some(840), Some(SpecialIndentType::Hanging(420)), None, None),
|
||||||
)
|
)
|
||||||
.add_level(
|
.add_level(
|
||||||
Level::new(
|
Level::new(
|
||||||
|
@ -82,7 +82,12 @@ fn create_default_numbering() -> AbstractNumbering {
|
||||||
LevelText::new("%3"),
|
LevelText::new("%3"),
|
||||||
LevelJc::new("left"),
|
LevelJc::new("left"),
|
||||||
)
|
)
|
||||||
.indent(1260, Some(SpecialIndentType::Hanging(420)), None),
|
.indent(
|
||||||
|
Some(1260),
|
||||||
|
Some(SpecialIndentType::Hanging(420)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.add_level(
|
.add_level(
|
||||||
Level::new(
|
Level::new(
|
||||||
|
@ -92,7 +97,12 @@ fn create_default_numbering() -> AbstractNumbering {
|
||||||
LevelText::new("%4."),
|
LevelText::new("%4."),
|
||||||
LevelJc::new("left"),
|
LevelJc::new("left"),
|
||||||
)
|
)
|
||||||
.indent(1680, Some(SpecialIndentType::Hanging(420)), None),
|
.indent(
|
||||||
|
Some(1680),
|
||||||
|
Some(SpecialIndentType::Hanging(420)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.add_level(
|
.add_level(
|
||||||
Level::new(
|
Level::new(
|
||||||
|
@ -102,7 +112,12 @@ fn create_default_numbering() -> AbstractNumbering {
|
||||||
LevelText::new("(%5)"),
|
LevelText::new("(%5)"),
|
||||||
LevelJc::new("left"),
|
LevelJc::new("left"),
|
||||||
)
|
)
|
||||||
.indent(2100, Some(SpecialIndentType::Hanging(420)), None),
|
.indent(
|
||||||
|
Some(2100),
|
||||||
|
Some(SpecialIndentType::Hanging(420)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.add_level(
|
.add_level(
|
||||||
Level::new(
|
Level::new(
|
||||||
|
@ -112,7 +127,12 @@ fn create_default_numbering() -> AbstractNumbering {
|
||||||
LevelText::new("%6"),
|
LevelText::new("%6"),
|
||||||
LevelJc::new("left"),
|
LevelJc::new("left"),
|
||||||
)
|
)
|
||||||
.indent(2520, Some(SpecialIndentType::Hanging(420)), None),
|
.indent(
|
||||||
|
Some(2520),
|
||||||
|
Some(SpecialIndentType::Hanging(420)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.add_level(
|
.add_level(
|
||||||
Level::new(
|
Level::new(
|
||||||
|
@ -122,7 +142,12 @@ fn create_default_numbering() -> AbstractNumbering {
|
||||||
LevelText::new("%7."),
|
LevelText::new("%7."),
|
||||||
LevelJc::new("left"),
|
LevelJc::new("left"),
|
||||||
)
|
)
|
||||||
.indent(2940, Some(SpecialIndentType::Hanging(420)), None),
|
.indent(
|
||||||
|
Some(2940),
|
||||||
|
Some(SpecialIndentType::Hanging(420)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.add_level(
|
.add_level(
|
||||||
Level::new(
|
Level::new(
|
||||||
|
@ -132,7 +157,12 @@ fn create_default_numbering() -> AbstractNumbering {
|
||||||
LevelText::new("(%8)"),
|
LevelText::new("(%8)"),
|
||||||
LevelJc::new("left"),
|
LevelJc::new("left"),
|
||||||
)
|
)
|
||||||
.indent(3360, Some(SpecialIndentType::Hanging(420)), None),
|
.indent(
|
||||||
|
Some(3360),
|
||||||
|
Some(SpecialIndentType::Hanging(420)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.add_level(
|
.add_level(
|
||||||
Level::new(
|
Level::new(
|
||||||
|
@ -142,6 +172,11 @@ fn create_default_numbering() -> AbstractNumbering {
|
||||||
LevelText::new("%9"),
|
LevelText::new("%9"),
|
||||||
LevelJc::new("left"),
|
LevelJc::new("left"),
|
||||||
)
|
)
|
||||||
.indent(3780, Some(SpecialIndentType::Hanging(420)), None),
|
.indent(
|
||||||
|
Some(3780),
|
||||||
|
Some(SpecialIndentType::Hanging(420)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,28 @@ use crate::types::*;
|
||||||
|
|
||||||
use super::super::errors::*;
|
use super::super::errors::*;
|
||||||
|
|
||||||
pub fn read_indent(
|
pub type ReadIndentResult = Result<
|
||||||
attrs: &[OwnedAttribute],
|
(
|
||||||
) -> Result<(i32, Option<i32>, Option<SpecialIndentType>), ReaderError> {
|
Option<i32>,
|
||||||
let mut start = 0;
|
Option<i32>,
|
||||||
|
Option<SpecialIndentType>,
|
||||||
|
Option<i32>,
|
||||||
|
),
|
||||||
|
ReaderError,
|
||||||
|
>;
|
||||||
|
|
||||||
|
pub fn read_indent(attrs: &[OwnedAttribute]) -> ReadIndentResult {
|
||||||
|
let mut start: Option<i32> = None;
|
||||||
|
let mut start_chars: Option<i32> = None;
|
||||||
let mut end: Option<i32> = None;
|
let mut end: Option<i32> = None;
|
||||||
let mut special: Option<SpecialIndentType> = None;
|
let mut special: Option<SpecialIndentType> = None;
|
||||||
|
|
||||||
for a in attrs {
|
for a in attrs {
|
||||||
let local_name = &a.name.local_name;
|
let local_name = &a.name.local_name;
|
||||||
if local_name == "left" || local_name == "start" {
|
if local_name == "left" || local_name == "start" {
|
||||||
start = i32::from_str(&a.value)?;
|
start = Some(i32::from_str(&a.value)?);
|
||||||
|
} else if local_name == "leftChars" || local_name == "startChars" {
|
||||||
|
start_chars = Some(i32::from_str(&a.value)?);
|
||||||
} else if local_name == "end" || local_name == "right" {
|
} else if local_name == "end" || local_name == "right" {
|
||||||
end = Some(i32::from_str(&a.value)?);
|
end = Some(i32::from_str(&a.value)?);
|
||||||
} else if local_name == "hanging" {
|
} else if local_name == "hanging" {
|
||||||
|
@ -26,5 +37,5 @@ pub fn read_indent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((start, end, special))
|
Ok((start, end, special, start_chars))
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,10 @@ impl ElementReader for Level {
|
||||||
let mut level_text = LevelText::new("");
|
let mut level_text = LevelText::new("");
|
||||||
let mut jc = LevelJc::new("left");
|
let mut jc = LevelJc::new("left");
|
||||||
|
|
||||||
let mut indent_start = 0;
|
let mut indent_start = None;
|
||||||
let mut special_indent = None;
|
let mut special_indent = None;
|
||||||
let mut indent_end = None;
|
let mut indent_end = None;
|
||||||
|
let mut start_chars = None;
|
||||||
let mut has_indent = false;
|
let mut has_indent = false;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -52,6 +53,7 @@ impl ElementReader for Level {
|
||||||
indent_start = i.0;
|
indent_start = i.0;
|
||||||
indent_end = i.1;
|
indent_end = i.1;
|
||||||
special_indent = i.2;
|
special_indent = i.2;
|
||||||
|
start_chars = i.3;
|
||||||
has_indent = true;
|
has_indent = true;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -65,7 +67,7 @@ impl ElementReader for Level {
|
||||||
l = l.paragraph_style(style_id);
|
l = l.paragraph_style(style_id);
|
||||||
}
|
}
|
||||||
if has_indent {
|
if has_indent {
|
||||||
l = l.indent(indent_start, special_indent, indent_end);
|
l = l.indent(indent_start, special_indent, indent_end, start_chars);
|
||||||
}
|
}
|
||||||
return Ok(l);
|
return Ok(l);
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,12 @@ mod tests {
|
||||||
LevelText::new("●"),
|
LevelText::new("●"),
|
||||||
LevelJc::new("left"),
|
LevelJc::new("left"),
|
||||||
)
|
)
|
||||||
.indent(720, Some(SpecialIndentType::Hanging(360)), None),
|
.indent(
|
||||||
|
Some(720),
|
||||||
|
Some(SpecialIndentType::Hanging(360)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.add_numbering(Numbering::new(1, 0));
|
.add_numbering(Numbering::new(1, 0));
|
||||||
|
|
|
@ -80,8 +80,8 @@ impl ElementReader for Paragraph {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
XMLElement::Indent => {
|
XMLElement::Indent => {
|
||||||
let (start, end, special) = read_indent(&attributes)?;
|
let (start, end, special, start_chars) = read_indent(&attributes)?;
|
||||||
p = p.indent(start, special, end);
|
p = p.indent(start, special, end, start_chars);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
XMLElement::Justification => {
|
XMLElement::Justification => {
|
||||||
|
@ -147,9 +147,10 @@ mod tests {
|
||||||
numbering_property: None,
|
numbering_property: None,
|
||||||
alignment: None,
|
alignment: None,
|
||||||
indent: Some(Indent::new(
|
indent: Some(Indent::new(
|
||||||
1470,
|
Some(1470),
|
||||||
Some(SpecialIndentType::Hanging(0)),
|
Some(SpecialIndentType::Hanging(0)),
|
||||||
Some(1270)
|
Some(1270),
|
||||||
|
None,
|
||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
has_numbering: false,
|
has_numbering: false,
|
||||||
|
@ -158,6 +159,40 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_read_indent_start_chars() {
|
||||||
|
let c = r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
|
||||||
|
<w:p>
|
||||||
|
<w:pPr>
|
||||||
|
<w:ind w:startChars="100" />
|
||||||
|
<w:rPr></w:rPr>
|
||||||
|
</w:pPr>
|
||||||
|
<w:r>
|
||||||
|
<w:rPr></w:rPr>
|
||||||
|
<w:t>a</w:t>
|
||||||
|
</w:r>
|
||||||
|
</w:p>
|
||||||
|
</w:document>"#;
|
||||||
|
let mut parser = EventReader::new(c.as_bytes());
|
||||||
|
let p = Paragraph::read(&mut parser, &[]).unwrap();
|
||||||
|
let s: Option<&str> = None;
|
||||||
|
assert_eq!(
|
||||||
|
p,
|
||||||
|
Paragraph {
|
||||||
|
children: vec![ParagraphChild::Run(Run::new().add_text("a"))],
|
||||||
|
property: ParagraphProperty {
|
||||||
|
run_property: RunProperty::new(),
|
||||||
|
style: ParagraphStyle::new(s),
|
||||||
|
numbering_property: None,
|
||||||
|
alignment: None,
|
||||||
|
indent: Some(Indent::new(None, None, None, Some(100))),
|
||||||
|
},
|
||||||
|
has_numbering: false,
|
||||||
|
attrs: Vec::new(),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_read_jc() {
|
fn test_read_jc() {
|
||||||
let c = r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
|
let c = r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
|
||||||
|
|
|
@ -38,8 +38,8 @@ impl ElementReader for Style {
|
||||||
}
|
}
|
||||||
// pPr
|
// pPr
|
||||||
XMLElement::Indent => {
|
XMLElement::Indent => {
|
||||||
let (start, end, special) = read_indent(&attributes)?;
|
let (start, end, special, start_chars) = read_indent(&attributes)?;
|
||||||
style = style.indent(start, special, end);
|
style = style.indent(start, special, end, start_chars);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
XMLElement::Justification => {
|
XMLElement::Justification => {
|
||||||
|
|
|
@ -89,16 +89,22 @@ impl XMLBuilder {
|
||||||
// i.e. <w:ind ... >
|
// i.e. <w:ind ... >
|
||||||
pub(crate) fn indent(
|
pub(crate) fn indent(
|
||||||
mut self,
|
mut self,
|
||||||
start: i32,
|
start: Option<i32>,
|
||||||
special_indent: Option<SpecialIndentType>,
|
special_indent: Option<SpecialIndentType>,
|
||||||
end: i32,
|
end: i32,
|
||||||
|
start_chars: Option<i32>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let start = &format!("{}", start);
|
let start = &format!("{}", start.unwrap_or(0));
|
||||||
let end = &format!("{}", end);
|
let end = &format!("{}", end);
|
||||||
let base = XmlEvent::start_element("w:ind")
|
let start_chars_value = format!("{}", start_chars.unwrap_or(0));
|
||||||
|
let mut base = XmlEvent::start_element("w:ind")
|
||||||
.attr("w:left", start)
|
.attr("w:left", start)
|
||||||
.attr("w:right", end);
|
.attr("w:right", end);
|
||||||
|
|
||||||
|
if start_chars.is_some() {
|
||||||
|
base = base.attr("w:leftChars", &start_chars_value);
|
||||||
|
}
|
||||||
|
|
||||||
match special_indent {
|
match special_indent {
|
||||||
Some(SpecialIndentType::FirstLine(v)) => self
|
Some(SpecialIndentType::FirstLine(v)) => self
|
||||||
.writer
|
.writer
|
||||||
|
|
|
@ -22,22 +22,25 @@ pub fn indent() -> Result<(), DocxError> {
|
||||||
let path = std::path::Path::new("./tests/output/indent.docx");
|
let path = std::path::Path::new("./tests/output/indent.docx");
|
||||||
let file = std::fs::File::create(&path).unwrap();
|
let file = std::fs::File::create(&path).unwrap();
|
||||||
Docx::new()
|
Docx::new()
|
||||||
.add_paragraph(
|
|
||||||
Paragraph::new()
|
|
||||||
.add_run(Run::new().add_text(DUMMY))
|
|
||||||
.indent(840, None, None),
|
|
||||||
)
|
|
||||||
.add_paragraph(Paragraph::new())
|
|
||||||
.add_paragraph(Paragraph::new().add_run(Run::new().add_text(DUMMY)).indent(
|
.add_paragraph(Paragraph::new().add_run(Run::new().add_text(DUMMY)).indent(
|
||||||
840,
|
Some(840),
|
||||||
Some(SpecialIndentType::FirstLine(720)),
|
None,
|
||||||
|
None,
|
||||||
None,
|
None,
|
||||||
))
|
))
|
||||||
.add_paragraph(Paragraph::new())
|
.add_paragraph(Paragraph::new())
|
||||||
.add_paragraph(Paragraph::new().add_run(Run::new().add_text(DUMMY)).indent(
|
.add_paragraph(Paragraph::new().add_run(Run::new().add_text(DUMMY)).indent(
|
||||||
1560,
|
Some(840),
|
||||||
|
Some(SpecialIndentType::FirstLine(720)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
))
|
||||||
|
.add_paragraph(Paragraph::new())
|
||||||
|
.add_paragraph(Paragraph::new().add_run(Run::new().add_text(DUMMY)).indent(
|
||||||
|
Some(1560),
|
||||||
Some(SpecialIndentType::Hanging(720)),
|
Some(SpecialIndentType::Hanging(720)),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
))
|
))
|
||||||
.build()
|
.build()
|
||||||
.pack(file)?;
|
.pack(file)?;
|
||||||
|
@ -370,7 +373,12 @@ pub fn user_numbering() -> Result<(), DocxError> {
|
||||||
LevelText::new("Section %1."),
|
LevelText::new("Section %1."),
|
||||||
LevelJc::new("left"),
|
LevelJc::new("left"),
|
||||||
)
|
)
|
||||||
.indent(1620, Some(SpecialIndentType::Hanging(320)), None),
|
.indent(
|
||||||
|
Some(1620),
|
||||||
|
Some(SpecialIndentType::Hanging(320)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.add_numbering(Numbering::new(2, 2))
|
.add_numbering(Numbering::new(2, 2))
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,8 +1,9 @@
|
||||||
export type IndentJSON = {
|
export type IndentJSON = {
|
||||||
start: number;
|
start: number | null;
|
||||||
end: number | null;
|
end: number | null;
|
||||||
specialIndent: {
|
specialIndent: {
|
||||||
type: "firstLine" | "hanging";
|
type: "firstLine" | "hanging";
|
||||||
val: number;
|
val: number;
|
||||||
} | null;
|
} | null;
|
||||||
|
startChars: number | null;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "docx-wasm",
|
"name": "docx-wasm",
|
||||||
"version": "0.0.47",
|
"version": "0.0.48",
|
||||||
"main": "dist/node/index.js",
|
"main": "dist/node/index.js",
|
||||||
"browser": "dist/web/index.js",
|
"browser": "dist/web/index.js",
|
||||||
"author": "bokuweb <bokuweb12@gmail.com>",
|
"author": "bokuweb <bokuweb12@gmail.com>",
|
||||||
|
|
|
@ -30,7 +30,11 @@ impl Level {
|
||||||
special_indent_size: Option<i32>,
|
special_indent_size: Option<i32>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let special_indent = create_special_indent(special_indent_kind, special_indent_size);
|
let special_indent = create_special_indent(special_indent_kind, special_indent_size);
|
||||||
self.0.paragraph_property = self.0.paragraph_property.indent(left, special_indent, None);
|
// end and start_chars is not supported fro wasm for now.
|
||||||
|
self.0.paragraph_property =
|
||||||
|
self.0
|
||||||
|
.paragraph_property
|
||||||
|
.indent(Some(left), special_indent, None, None);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,10 @@ impl Paragraph {
|
||||||
special_indent_size: Option<i32>,
|
special_indent_size: Option<i32>,
|
||||||
) -> Paragraph {
|
) -> Paragraph {
|
||||||
let special_indent = create_special_indent(special_indent_kind, special_indent_size);
|
let special_indent = create_special_indent(special_indent_kind, special_indent_size);
|
||||||
self.0.property = self.0.property.indent(left, special_indent, None);
|
self.0.property = self
|
||||||
|
.0
|
||||||
|
.property
|
||||||
|
.indent(Some(left), special_indent, None, None);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue