fix: read levelOverride (#61)

* fix: read levelOverride

* spec: update snaps
main
bokuweb 2020-04-21 19:02:36 +09:00 committed by GitHub
parent 83d7dc2b01
commit 63368592b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 183 additions and 10 deletions

View File

@ -0,0 +1,33 @@
use crate::documents::BuildXML;
// use crate::xml_builder::*;
use serde::Serialize;
/*
17.9.8 lvlOverride (Numbering Level Definition Override)
This element specifies an optional override which shall be applied in place of zero or more levels from the abstract numbering definition for a given numbering definition instance. Each instance of this element is used to override the appearance and behavior of a given numbering level definition within the given abstract numbering definition.
*/
#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct LevelOverride {
pub level: usize,
pub start: Option<usize>,
}
impl LevelOverride {
pub fn new(level: usize) -> LevelOverride {
LevelOverride { level, start: None }
}
pub fn start(mut self, start: usize) -> LevelOverride {
self.start = Some(start);
self
}
}
// TODO: Now read only
impl BuildXML for LevelOverride {
fn build(&self) -> Vec<u8> {
vec![]
}
}

View File

@ -27,6 +27,7 @@ mod italic_cs;
mod justification;
mod level;
mod level_jc;
mod level_override;
mod level_text;
mod mc_fallback;
mod name;
@ -103,6 +104,7 @@ pub use italic_cs::*;
pub use justification::*;
pub use level::*;
pub use level_jc::*;
pub use level_override::*;
pub use level_text::*;
pub use mc_fallback::*;
pub use name::*;

View File

@ -1,6 +1,7 @@
use crate::documents::BuildXML;
use crate::xml_builder::*;
use super::*;
use serde::Serialize;
#[derive(Debug, Clone, PartialEq, Serialize)]
@ -8,6 +9,7 @@ use serde::Serialize;
pub struct Numbering {
id: usize,
abstract_num_id: usize,
level_overrides: Vec<LevelOverride>,
}
impl Numbering {
@ -15,8 +17,14 @@ impl Numbering {
Self {
id,
abstract_num_id,
level_overrides: vec![],
}
}
pub fn overrides(mut self, overrides: Vec<LevelOverride>) -> Self {
self.level_overrides = overrides;
self
}
}
impl BuildXML for Numbering {
@ -47,4 +55,40 @@ mod tests {
</w:num>"#
);
}
/* TODO: enable when builder implemented
#[test]
fn test_numbering_override() {
let c = Numbering::new(0, 2);
let overrides = vec![
LevelOverride::new(0).start(1),
LevelOverride::new(1).start(1),
];
let b = c.overrides(overrides).build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:num w:numId="0">
<w:abstractNumId w:val="2" />
<w:lvlOverride w:ilvl="0">
<w:startOverride w:val="1"/>
</w:lvlOverride>
<w:lvlOverride w:ilvl="1">
<w:startOverride w:val="1"/>
</w:lvlOverride>
</w:num>"#
);
}
*/
#[test]
fn test_numbering_override_json() {
let c = Numbering::new(0, 2);
let overrides = vec![
LevelOverride::new(0).start(1),
LevelOverride::new(1).start(1),
];
assert_eq!(
serde_json::to_string(&c.overrides(overrides)).unwrap(),
r#"{"id":0,"abstractNumId":2,"levelOverrides":[{"level":0,"start":1},{"level":1,"start":1}]}"#
);
}
}

View File

@ -1,7 +1,9 @@
use crate::documents::BuildXML;
use crate::xml_builder::*;
#[derive(Debug, Clone, PartialEq)]
use serde::Serialize;
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct NumberingId {
pub id: usize,
}

View File

@ -0,0 +1,39 @@
use std::io::Read;
use std::str::FromStr;
use xml::attribute::OwnedAttribute;
use xml::reader::{EventReader, XmlEvent};
use super::*;
impl ElementReader for LevelOverride {
fn read<R: Read>(
r: &mut EventReader<R>,
attrs: &[OwnedAttribute],
) -> Result<Self, ReaderError> {
let mut o = LevelOverride::new(usize::from_str(&attrs[0].value)?);
loop {
let e = r.next();
match e {
Ok(XmlEvent::StartElement {
attributes, name, ..
}) => {
let e = XMLElement::from_str(&name.local_name).unwrap();
if let XMLElement::StartOverride = e {
let val = usize::from_str(&attributes[0].value)?;
o = o.start(val);
continue;
}
}
Ok(XmlEvent::EndElement { name, .. }) => {
let e = XMLElement::from_str(&name.local_name).unwrap();
if e == XMLElement::LvlOverride {
return Ok(o);
}
}
Err(_) => return Err(ReaderError::XMLReadError),
_ => {}
}
}
}
}

View File

@ -26,6 +26,7 @@ mod wp_anchor;
mod wps_shape;
mod wps_text_box;
mod xml_element;
mod level_override;
use std::io::Cursor;
use zip;

View File

@ -70,6 +70,8 @@ impl FromXML for Numberings {
}
}
let mut abs_num_id = 0;
let mut level_overrides = vec![];
loop {
let e = parser.next();
match e {
@ -77,15 +79,24 @@ impl FromXML for Numberings {
attributes, name, ..
}) => {
let e = XMLElement::from_str(&name.local_name).unwrap();
if let XMLElement::AbstractNumberingId = e {
abs_num_id = usize::from_str(&attributes[0].value)?;
match e {
XMLElement::AbstractNumberingId => {
abs_num_id = usize::from_str(&attributes[0].value)?
}
XMLElement::LvlOverride => {
let o =
LevelOverride::read(&mut parser, &attributes)?;
level_overrides.push(o);
}
_ => {}
}
}
Ok(XmlEvent::EndElement { name, .. }) => {
let e = XMLElement::from_str(&name.local_name).unwrap();
if let XMLElement::Num = e {
let num = Numbering::new(id, abs_num_id);
nums =
nums.add_numbering(Numbering::new(id, abs_num_id));
nums.add_numbering(num.overrides(level_overrides));
break;
}
}
@ -204,4 +215,35 @@ mod tests {
.add_numbering(Numbering::new(1, 0));
assert_eq!(n, nums)
}
#[test]
fn test_numberings_from_xml_with_override() {
let xml = r#"<w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" >
<w:abstractNum w:abstractNumId="0">
<w:multiLevelType w:val="hybridMultilevel"/>
</w:abstractNum>
<w:num w:numId="1">
<w:abstractNumId w:val="0"></w:abstractNumId>
<w:lvlOverride w:ilvl="0">
<w:startOverride w:val="1"/>
</w:lvlOverride>
<w:lvlOverride w:ilvl="1">
<w:startOverride w:val="1"/>
</w:lvlOverride>
</w:num>
</w:numbering>"#;
let n = Numberings::from_xml(xml.as_bytes()).unwrap();
let mut nums = Numberings::new();
let overrides = vec![
LevelOverride::new(0).start(1),
LevelOverride::new(1).start(1),
];
let num = Numbering::new(1, 0).overrides(overrides);
dbg!(&num);
nums = nums
.add_abstract_numbering(AbstractNumbering::new(0))
.add_numbering(num);
assert_eq!(n, nums)
}
}

View File

@ -70,6 +70,8 @@ pub enum XMLElement {
Relationships,
AbstractNumbering,
AbstractNumberingId,
LvlOverride,
StartOverride,
Level,
Numbering,
Num,
@ -217,6 +219,8 @@ impl FromStr for XMLElement {
"drawing" => Ok(XMLElement::Drawing),
"txbxContent" => Ok(XMLElement::TxbxContent),
"pict" => Ok(XMLElement::Pict),
"lvlOverride" => Ok(XMLElement::LvlOverride),
"startOverride" => Ok(XMLElement::StartOverride),
_ => Ok(XMLElement::Unsupported),
}
}

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

View File

@ -20,6 +20,12 @@ export type AbstractNumberingJSON = {
export type NumberingJSON = {
id: number;
abstractNumId: number;
LevelOverrides: LevelOverrideJSON[];
};
export type LevelOverrideJSON = {
level: number;
start: number;
};
export type NumberingsJSON = {