parent
83d7dc2b01
commit
63368592b8
|
@ -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![]
|
||||
}
|
||||
}
|
|
@ -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::*;
|
||||
|
|
|
@ -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}]}"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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 = {
|
||||
|
|
Loading…
Reference in New Issue