* 0.0.275

* fix

* fix: hyperlink child types

* read hyperlink rels

* update snaps

* update

* 0.0.275

* fix
main
bokuweb 2022-08-09 15:32:17 +09:00 committed by GitHub
parent c44b62dac4
commit 0f5e1d1cdc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 146 additions and 60 deletions

View File

@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## docx-wasm@0.0.275 (8. Aug, 2022)
- re enable Hyperlink interface.
## docx-wasm@0.0.273 (6. Jul, 2022) ## docx-wasm@0.0.273 (6. Jul, 2022)
- [Breaking] Hyperlink interface. - [Breaking] Hyperlink interface.

View File

@ -10,7 +10,7 @@ pub struct DocumentRels {
pub has_comments: bool, pub has_comments: bool,
pub has_numberings: bool, pub has_numberings: bool,
pub images: Vec<(String, String)>, pub images: Vec<(String, String)>,
pub hyperlinks: Vec<(String, String)>, pub hyperlinks: Vec<(String, String, String)>,
pub custom_xml_count: usize, pub custom_xml_count: usize,
pub header_count: usize, pub header_count: usize,
pub footer_count: usize, pub footer_count: usize,
@ -31,8 +31,14 @@ impl DocumentRels {
self self
} }
pub fn add_hyperlinks(mut self, id: impl Into<String>, path: impl Into<String>) -> Self { pub fn add_hyperlinks(
self.hyperlinks.push((id.into(), path.into())); mut self,
id: impl Into<String>,
path: impl Into<String>,
r#type: impl Into<String>,
) -> Self {
self.hyperlinks
.push((id.into(), path.into(), r#type.into()));
self self
} }
} }
@ -112,12 +118,12 @@ impl BuildXML for DocumentRels {
) )
} }
for (id, path) in self.hyperlinks.iter() { for (id, path, r#type) in self.hyperlinks.iter() {
b = b.relationship_with_mode( b = b.relationship_with_mode(
id, id,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
path, path,
"External", r#type,
) )
} }

View File

@ -128,6 +128,8 @@ pub struct Docx {
pub themes: Vec<Theme>, pub themes: Vec<Theme>,
// reader only // reader only
pub images: Vec<(String, String, Image, Png)>, pub images: Vec<(String, String, Image, Png)>,
// reader only
pub hyperlinks: Vec<(String, String, String)>,
} }
impl Default for Docx { impl Default for Docx {
@ -168,6 +170,7 @@ impl Default for Docx {
custom_item_rels: vec![], custom_item_rels: vec![],
themes: vec![], themes: vec![],
images: vec![], images: vec![],
hyperlinks: vec![],
} }
} }
} }
@ -242,6 +245,18 @@ impl Docx {
self self
} }
// reader only
pub(crate) fn add_hyperlink(
mut self,
id: impl Into<String>,
path: impl Into<String>,
r#type: impl Into<String>,
) -> Self {
self.hyperlinks
.push((id.into(), path.into(), r#type.into()));
self
}
pub fn comments(mut self, c: Comments) -> Self { pub fn comments(mut self, c: Comments) -> Self {
self.comments = c; self.comments = c;
self self
@ -692,7 +707,9 @@ impl Docx {
self.comments.add_comments(comments); self.comments.add_comments(comments);
for (id, d) in hyperlink_map { for (id, d) in hyperlink_map {
self.document_rels.hyperlinks.push((id, d)); self.document_rels
.hyperlinks
.push((id, d, "External".to_string())); // Now support external only
} }
} }
@ -989,7 +1006,8 @@ fn push_comment_and_comment_extended(
let comment_extended = CommentExtended::new(para_id); let comment_extended = CommentExtended::new(para_id);
if let Some(parent_comment_id) = comment.parent_comment_id { if let Some(parent_comment_id) = comment.parent_comment_id {
if let Some(parent_para_id) = comment_map.get(&parent_comment_id) { if let Some(parent_para_id) = comment_map.get(&parent_comment_id) {
comments_extended.push(comment_extended.parent_paragraph_id(parent_para_id.clone())); comments_extended
.push(comment_extended.parent_paragraph_id(parent_para_id.clone()));
} }
} else { } else {
comments_extended.push(comment_extended); comments_extended.push(comment_extended);

View File

@ -13,11 +13,11 @@ pub type RId = String;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct ReadDocumentRels { pub struct ReadDocumentRels {
rels: BTreeMap<String, HashSet<(RId, PathBuf)>>, rels: BTreeMap<String, HashSet<(RId, PathBuf, Option<String>)>>,
} }
impl ReadDocumentRels { impl ReadDocumentRels {
pub fn find_target_path(&self, target: &str) -> Option<Vec<(RId, PathBuf)>> { pub fn find_target_path(&self, target: &str) -> Option<Vec<(RId, PathBuf, Option<String>)>> {
self.rels self.rels
.get(target) .get(target)
.map(|s| s.clone().into_iter().collect()) .map(|s| s.clone().into_iter().collect())
@ -57,23 +57,35 @@ fn read_rels_xml<R: Read>(
if let XMLElement::Relationship = e { if let XMLElement::Relationship = e {
let mut rel_type = "".to_owned(); let mut rel_type = "".to_owned();
let mut rid = "".to_owned(); let mut rid = "".to_owned();
let mut target = PathBuf::default(); let mut target_mode = None;
let mut target_string = "".to_owned();
for a in attributes { for a in attributes {
let local_name = &a.name.local_name; let local_name = &a.name.local_name;
if local_name == "Type" { if local_name == "Type" {
rel_type = a.value.to_owned(); rel_type = a.value.to_owned();
} else if local_name == "Target" { } else if local_name == "Target" {
target = Path::new(dir.as_ref()).join(a.value); // target_str = Path::new(dir.as_ref()).join(a.value);
target_string = a.value.to_owned();
} else if local_name == "Id" { } else if local_name == "Id" {
rid = a.value.to_owned(); rid = a.value.to_owned();
} else if local_name == "TargetMode" {
target_mode = Some(a.value.to_owned());
} }
} }
let target = if !rel_type.ends_with("hyperlink") {
Path::new(dir.as_ref()).join(target_string)
} else {
Path::new("").join(target_string)
};
let current = rels.rels.remove(&rel_type); let current = rels.rels.remove(&rel_type);
if let Some(mut paths) = current { if let Some(mut paths) = current {
paths.insert((rid, target)); paths.insert((rid, target, target_mode));
rels.rels.insert(rel_type, paths); rels.rels.insert(rel_type, paths);
} else { } else {
let s: HashSet<(RId, PathBuf)> = vec![(rid, target)].into_iter().collect(); let s: HashSet<(RId, PathBuf, Option<String>)> =
vec![(rid, target, target_mode)].into_iter().collect();
rels.rels.insert(rel_type, s); rels.rels.insert(rel_type, s);
} }
continue; continue;

View File

@ -97,6 +97,8 @@ const THEME_TYPE: &str =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"; "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
const IMAGE_TYPE: &str = const IMAGE_TYPE: &str =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"; "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
const HYPERLINK_TYPE: &str =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
// 2011 // 2011
const COMMENTS_EXTENDED_TYPE: &str = const COMMENTS_EXTENDED_TYPE: &str =
"http://schemas.microsoft.com/office/2011/relationships/commentsExtended"; "http://schemas.microsoft.com/office/2011/relationships/commentsExtended";
@ -109,7 +111,7 @@ fn read_headers(
let headers: HashMap<RId, Header> = header_paths let headers: HashMap<RId, Header> = header_paths
.unwrap_or_default() .unwrap_or_default()
.into_iter() .into_iter()
.filter_map(|(rid, path)| { .filter_map(|(rid, path, ..)| {
let data = read_zip(archive, path.to_str().expect("should have header path.")); let data = read_zip(archive, path.to_str().expect("should have header path."));
if let Ok(d) = data { if let Ok(d) = data {
if let Ok(h) = Header::from_xml(&d[..]) { if let Ok(h) = Header::from_xml(&d[..]) {
@ -130,7 +132,7 @@ fn read_footers(
let footers: HashMap<RId, Footer> = footer_paths let footers: HashMap<RId, Footer> = footer_paths
.unwrap_or_default() .unwrap_or_default()
.into_iter() .into_iter()
.filter_map(|(rid, path)| { .filter_map(|(rid, path, ..)| {
let data = read_zip(archive, path.to_str().expect("should have footer path.")); let data = read_zip(archive, path.to_str().expect("should have footer path."));
if let Ok(d) = data { if let Ok(d) = data {
if let Ok(h) = Footer::from_xml(&d[..]) { if let Ok(h) = Footer::from_xml(&d[..]) {
@ -148,7 +150,7 @@ fn read_themes(rels: &ReadDocumentRels, archive: &mut ZipArchive<Cursor<&[u8]>>)
theme_paths theme_paths
.unwrap_or_default() .unwrap_or_default()
.into_iter() .into_iter()
.filter_map(|(_rid, path)| { .filter_map(|(_rid, path, ..)| {
let data = read_zip(archive, path.to_str().expect("should have footer path.")); let data = read_zip(archive, path.to_str().expect("should have footer path."));
if let Ok(d) = data { if let Ok(d) = data {
if let Ok(h) = Theme::from_xml(&d[..]) { if let Ok(h) = Theme::from_xml(&d[..]) {
@ -209,7 +211,7 @@ pub fn read_docx(buf: &[u8]) -> Result<Docx, ReaderError> {
// Read commentsExtended // Read commentsExtended
let comments_extended_path = rels.find_target_path(COMMENTS_EXTENDED_TYPE); let comments_extended_path = rels.find_target_path(COMMENTS_EXTENDED_TYPE);
let comments_extended = if let Some(comments_extended_path) = comments_extended_path { let comments_extended = if let Some(comments_extended_path) = comments_extended_path {
if let Some((_, comments_extended_path)) = comments_extended_path.get(0) { if let Some((_, comments_extended_path, ..)) = comments_extended_path.get(0) {
let data = read_zip( let data = read_zip(
&mut archive, &mut archive,
comments_extended_path comments_extended_path
@ -231,7 +233,7 @@ pub fn read_docx(buf: &[u8]) -> Result<Docx, ReaderError> {
// Read comments // Read comments
let comments_path = rels.find_target_path(COMMENTS_TYPE); let comments_path = rels.find_target_path(COMMENTS_TYPE);
let comments = if let Some(paths) = comments_path { let comments = if let Some(paths) = comments_path {
if let Some((_, comments_path)) = paths.get(0) { if let Some((_, comments_path, ..)) = paths.get(0) {
let data = read_zip( let data = read_zip(
&mut archive, &mut archive,
comments_path.to_str().expect("should have comments."), comments_path.to_str().expect("should have comments."),
@ -360,7 +362,7 @@ pub fn read_docx(buf: &[u8]) -> Result<Docx, ReaderError> {
// Read styles // Read styles
let style_path = rels.find_target_path(STYLE_RELATIONSHIP_TYPE); let style_path = rels.find_target_path(STYLE_RELATIONSHIP_TYPE);
if let Some(paths) = style_path { if let Some(paths) = style_path {
if let Some((_, style_path)) = paths.get(0) { if let Some((_, style_path, ..)) = paths.get(0) {
let data = read_zip( let data = read_zip(
&mut archive, &mut archive,
style_path.to_str().expect("should have styles"), style_path.to_str().expect("should have styles"),
@ -373,7 +375,7 @@ pub fn read_docx(buf: &[u8]) -> Result<Docx, ReaderError> {
// Read numberings // Read numberings
let num_path = rels.find_target_path(NUMBERING_RELATIONSHIP_TYPE); let num_path = rels.find_target_path(NUMBERING_RELATIONSHIP_TYPE);
if let Some(paths) = num_path { if let Some(paths) = num_path {
if let Some((_, num_path)) = paths.get(0) { if let Some((_, num_path, ..)) = paths.get(0) {
let data = read_zip( let data = read_zip(
&mut archive, &mut archive,
num_path.to_str().expect("should have numberings"), num_path.to_str().expect("should have numberings"),
@ -386,7 +388,7 @@ pub fn read_docx(buf: &[u8]) -> Result<Docx, ReaderError> {
// Read settings // Read settings
let settings_path = rels.find_target_path(SETTINGS_TYPE); let settings_path = rels.find_target_path(SETTINGS_TYPE);
if let Some(paths) = settings_path { if let Some(paths) = settings_path {
if let Some((_, settings_path)) = paths.get(0) { if let Some((_, settings_path, ..)) = paths.get(0) {
let data = read_zip( let data = read_zip(
&mut archive, &mut archive,
settings_path.to_str().expect("should have settings"), settings_path.to_str().expect("should have settings"),
@ -399,7 +401,7 @@ pub fn read_docx(buf: &[u8]) -> Result<Docx, ReaderError> {
// Read web settings // Read web settings
let web_settings_path = rels.find_target_path(WEB_SETTINGS_TYPE); let web_settings_path = rels.find_target_path(WEB_SETTINGS_TYPE);
if let Some(paths) = web_settings_path { if let Some(paths) = web_settings_path {
if let Some((_, web_settings_path)) = paths.get(0) { if let Some((_, web_settings_path, ..)) = paths.get(0) {
let data = read_zip( let data = read_zip(
&mut archive, &mut archive,
web_settings_path web_settings_path
@ -413,11 +415,23 @@ pub fn read_docx(buf: &[u8]) -> Result<Docx, ReaderError> {
// Read media // Read media
let media = rels.find_target_path(IMAGE_TYPE); let media = rels.find_target_path(IMAGE_TYPE);
if let Some(paths) = media { if let Some(paths) = media {
for (id, media) in paths { for (id, media, ..) in paths {
if let Ok(data) = read_zip(&mut archive, media.to_str().expect("should have media")) { if let Ok(data) = read_zip(&mut archive, media.to_str().expect("should have media")) {
docx = docx.add_image(id, media.to_str().unwrap().to_string(), data); docx = docx.add_image(id, media.to_str().unwrap().to_string(), data);
} }
} }
} }
// Read hyperlinks
let links = rels.find_target_path(HYPERLINK_TYPE);
if let Some(paths) = links {
for (id, target, mode) in paths {
if let Some(mode) = mode {
docx =
docx.add_hyperlink(id, target.to_str().expect("should convert to str"), mode);
}
}
}
Ok(docx) Ok(docx)
} }

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

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

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

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

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

@ -49,6 +49,7 @@ export type DocxJSON = {
themes: ThemeJSON[]; themes: ThemeJSON[];
//(id, path, base64 encoded original image data, base64 encoded png image data) //(id, path, base64 encoded original image data, base64 encoded png image data)
images: [string, string, string, string][]; images: [string, string, string, string][];
hyperlinks: [string, string, string][];
}; };
export type SettingsJSON = { export type SettingsJSON = {

View File

@ -91,6 +91,7 @@ export type HyperlinkJSON = {
| { | {
type: "anchor"; type: "anchor";
anchor: string; anchor: string;
children: HyperlinkChildJSON[];
}; };
}; };

View File

@ -1,6 +1,6 @@
{ {
"name": "docx-wasm", "name": "docx-wasm",
"version": "0.0.274-image-test8", "version": "0.0.276-rc4",
"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>",

View File

@ -546,6 +546,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -1406,6 +1407,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -1852,6 +1854,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -4176,6 +4179,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -5480,6 +5484,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -5840,6 +5845,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -7157,6 +7163,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -10150,6 +10157,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -11031,6 +11039,13 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [
Array [
"rId4",
"https://google.com/",
"External",
],
],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -12327,6 +12342,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [ "images": Array [
Array [ Array [
"rId4", "rId4",
@ -13270,6 +13286,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -13677,6 +13694,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -16219,6 +16237,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -18394,6 +18413,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -19511,6 +19531,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -22379,6 +22400,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -23738,6 +23760,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -27062,6 +27085,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -43596,6 +43620,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -44612,6 +44637,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -46561,6 +46587,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -50436,6 +50463,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -51452,6 +51480,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {
@ -52499,6 +52528,7 @@ Object {
"images": Array [], "images": Array [],
}, },
"fontTable": Object {}, "fontTable": Object {},
"hyperlinks": Array [],
"images": Array [], "images": Array [],
"media": Array [], "media": Array [],
"numberings": Object { "numberings": Object {