Fix support hyperlink reader (#508)
* fix * fix: support external link * wip * fix Co-authored-by: bokuweb <bokuweb@bokuwebnombp.lan>main
parent
674499a436
commit
a346cd1a16
|
@ -4,17 +4,16 @@ pub fn main() -> Result<(), DocxError> {
|
|||
let path = std::path::Path::new("./output/hyperlink.docx");
|
||||
let file = std::fs::File::create(&path).unwrap();
|
||||
Docx::new()
|
||||
.add_paragraph(
|
||||
Paragraph::new().add_hyperlink(
|
||||
Hyperlink::new()
|
||||
.anchor("anchor")
|
||||
.add_run(Run::new().add_text("Hello")),
|
||||
),
|
||||
)
|
||||
.add_paragraph(Paragraph::new().add_hyperlink(
|
||||
Hyperlink::new("anchor", HyperlinkType::Anchor).add_run(Run::new().add_text("Hello")),
|
||||
))
|
||||
.add_bookmark_start(1, "anchor")
|
||||
.add_paragraph(
|
||||
Paragraph::new()
|
||||
.add_run(Run::new().add_text("World"))
|
||||
.add_hyperlink(
|
||||
Hyperlink::new("https://google.com", HyperlinkType::External)
|
||||
.add_run(Run::new().add_text(" World")),
|
||||
)
|
||||
.page_break_before(true),
|
||||
)
|
||||
.add_bookmark_end(1)
|
||||
|
|
|
@ -10,6 +10,7 @@ pub struct DocumentRels {
|
|||
pub has_comments: bool,
|
||||
pub has_numberings: bool,
|
||||
pub images: Vec<(String, String)>,
|
||||
pub hyperlinks: Vec<(String, String)>,
|
||||
pub custom_xml_count: usize,
|
||||
pub header_count: usize,
|
||||
pub footer_count: usize,
|
||||
|
@ -29,6 +30,11 @@ impl DocumentRels {
|
|||
self.images.push((id.into(), path.into()));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_hyperlinks(mut self, id: impl Into<String>, path: impl Into<String>) -> Self {
|
||||
self.hyperlinks.push((id.into(), path.into()));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl BuildXML for DocumentRels {
|
||||
|
@ -106,6 +112,15 @@ impl BuildXML for DocumentRels {
|
|||
)
|
||||
}
|
||||
|
||||
for (id, path) in self.hyperlinks.iter() {
|
||||
b = b.relationship_with_mode(
|
||||
id,
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
|
||||
path,
|
||||
"External",
|
||||
)
|
||||
}
|
||||
|
||||
b.close().build()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,34 +2,51 @@ use serde::Serialize;
|
|||
|
||||
use super::*;
|
||||
use crate::documents::BuildXML;
|
||||
use crate::xml_builder::*;
|
||||
use crate::types::*;
|
||||
use crate::{create_hyperlink_rid, generate_hyperlink_id, xml_builder::*};
|
||||
|
||||
#[derive(Serialize, Debug, Clone, PartialEq, Default)]
|
||||
#[derive(Serialize, Debug, Clone, PartialEq)]
|
||||
#[serde(tag = "type")]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum HyperlinkData {
|
||||
External {
|
||||
rid: String,
|
||||
// path is writer only
|
||||
#[serde(skip_serializing_if = "String::is_empty")]
|
||||
path: String,
|
||||
},
|
||||
Anchor {
|
||||
anchor: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Hyperlink {
|
||||
pub rid: Option<String>,
|
||||
pub anchor: Option<String>,
|
||||
pub history: bool,
|
||||
#[serde(flatten)]
|
||||
pub link: HyperlinkData,
|
||||
pub history: Option<usize>,
|
||||
pub children: Vec<ParagraphChild>,
|
||||
}
|
||||
|
||||
impl Hyperlink {
|
||||
pub fn new() -> Self {
|
||||
Hyperlink::default()
|
||||
}
|
||||
|
||||
pub fn rid(mut self, rid: impl Into<String>) -> Self {
|
||||
self.rid = Some(rid.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn anchor(mut self, anchor: impl Into<String>) -> Self {
|
||||
self.anchor = Some(anchor.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn history(mut self) -> Self {
|
||||
self.history = true;
|
||||
self
|
||||
pub fn new(value: impl Into<String>, t: HyperlinkType) -> Self {
|
||||
let link = {
|
||||
match t {
|
||||
HyperlinkType::External => HyperlinkData::External {
|
||||
rid: create_hyperlink_rid(generate_hyperlink_id()),
|
||||
path: value.into(),
|
||||
},
|
||||
HyperlinkType::Anchor => HyperlinkData::Anchor {
|
||||
anchor: value.into(),
|
||||
},
|
||||
}
|
||||
};
|
||||
Hyperlink {
|
||||
link,
|
||||
history: None,
|
||||
children: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_run(mut self, run: Run) -> Self {
|
||||
|
@ -81,11 +98,24 @@ impl Hyperlink {
|
|||
|
||||
impl BuildXML for Hyperlink {
|
||||
fn build(&self) -> Vec<u8> {
|
||||
let b = XMLBuilder::new();
|
||||
b.open_hyperlink(self.rid.as_ref(), self.anchor.as_ref(), self.history)
|
||||
.add_children(&self.children)
|
||||
.close()
|
||||
.build()
|
||||
let mut b = XMLBuilder::new();
|
||||
match self.link {
|
||||
HyperlinkData::Anchor { ref anchor } => {
|
||||
b = b.open_hyperlink(
|
||||
None,
|
||||
Some(anchor.clone()).as_ref(),
|
||||
Some(self.history.unwrap_or(1)),
|
||||
)
|
||||
}
|
||||
HyperlinkData::External { ref rid, .. } => {
|
||||
b = b.open_hyperlink(
|
||||
Some(rid.clone()).as_ref(),
|
||||
None,
|
||||
Some(self.history.unwrap_or(1)),
|
||||
)
|
||||
}
|
||||
};
|
||||
b.add_children(&self.children).close().build()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,13 +129,11 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_hyperlink() {
|
||||
let l = Hyperlink::new()
|
||||
.anchor("ToC1")
|
||||
.add_run(Run::new().add_text("hello"));
|
||||
let l = Hyperlink::new("ToC1", HyperlinkType::Anchor).add_run(Run::new().add_text("hello"));
|
||||
let b = l.build();
|
||||
assert_eq!(
|
||||
str::from_utf8(&b).unwrap(),
|
||||
r#"<w:hyperlink w:anchor="ToC1"><w:r><w:rPr /><w:t xml:space="preserve">hello</w:t></w:r></w:hyperlink>"#
|
||||
r#"<w:hyperlink w:anchor="ToC1" w:history="1"><w:r><w:rPr /><w:t xml:space="preserve">hello</w:t></w:r></w:hyperlink>"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,8 +85,7 @@ impl BuildXML for Vec<TableOfContentsItem> {
|
|||
|
||||
if t.instr.hyperlink {
|
||||
p = p.add_hyperlink(
|
||||
Hyperlink::new()
|
||||
.anchor(&t.toc_key)
|
||||
Hyperlink::new(&t.toc_key, crate::types::HyperlinkType::Anchor)
|
||||
.add_run(run)
|
||||
.add_run(Run::new().add_tab())
|
||||
.add_run(page_ref),
|
||||
|
@ -120,8 +119,7 @@ impl BuildXML for Vec<TableOfContentsItem> {
|
|||
|
||||
if t.instr.hyperlink {
|
||||
p = p.add_hyperlink(
|
||||
Hyperlink::new()
|
||||
.anchor(&t.toc_key)
|
||||
Hyperlink::new(&t.toc_key, HyperlinkType::Anchor)
|
||||
.add_run(run)
|
||||
.add_run(Run::new().add_tab())
|
||||
.add_run(page_ref),
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#[cfg(not(test))]
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
#[cfg(not(test))]
|
||||
static HYPERLINK_ID: AtomicUsize = AtomicUsize::new(1);
|
||||
|
||||
#[cfg(not(test))]
|
||||
pub fn generate_hyperlink_id() -> usize {
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
let id = HYPERLINK_ID.load(Ordering::Relaxed);
|
||||
HYPERLINK_ID.store(id.wrapping_add(1), Ordering::Relaxed);
|
||||
id
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn generate_hyperlink_id() -> usize {
|
||||
123
|
||||
}
|
||||
|
||||
pub fn create_hyperlink_rid(id: usize) -> String {
|
||||
format!("rIdHyperlink{}", id)
|
||||
}
|
|
@ -18,6 +18,7 @@ mod footer_id;
|
|||
mod header;
|
||||
mod header_id;
|
||||
mod history_id;
|
||||
mod hyperlink_id;
|
||||
mod numberings;
|
||||
mod paragraph_id;
|
||||
mod paragraph_property_change_id;
|
||||
|
@ -36,6 +37,7 @@ mod xml_docx;
|
|||
|
||||
pub(crate) use build_xml::BuildXML;
|
||||
pub(crate) use history_id::HistoryId;
|
||||
pub(crate) use hyperlink_id::*;
|
||||
use image::ImageFormat;
|
||||
pub(crate) use paragraph_id::*;
|
||||
pub(crate) use paragraph_property_change_id::ParagraphPropertyChangeId;
|
||||
|
@ -478,7 +480,7 @@ impl Docx {
|
|||
pub fn build(mut self) -> XMLDocx {
|
||||
self.reset();
|
||||
|
||||
self.update_comments();
|
||||
self.update_dependencies();
|
||||
|
||||
let tocs: Vec<(usize, Box<TableOfContents>)> = self
|
||||
.document
|
||||
|
@ -572,7 +574,7 @@ impl Docx {
|
|||
pub fn json_with_update_comments(&mut self) -> String {
|
||||
self.reset();
|
||||
|
||||
self.update_comments();
|
||||
self.update_dependencies();
|
||||
serde_json::to_string_pretty(&self).unwrap()
|
||||
}
|
||||
|
||||
|
@ -597,11 +599,13 @@ impl Docx {
|
|||
}
|
||||
|
||||
// Traverse and clone comments from document and add to comments node.
|
||||
fn update_comments(&mut self) {
|
||||
fn update_dependencies(&mut self) {
|
||||
let mut comments: Vec<Comment> = vec![];
|
||||
let mut comments_extended: Vec<CommentExtended> = vec![];
|
||||
|
||||
let mut comment_map: HashMap<usize, String> = HashMap::new();
|
||||
|
||||
let mut hyperlink_map: HashMap<String, String> = HashMap::new();
|
||||
|
||||
for child in &self.document.children {
|
||||
match child {
|
||||
DocumentChild::Paragraph(paragraph) => {
|
||||
|
@ -610,6 +614,9 @@ impl Docx {
|
|||
self.insert_comment_to_map(&mut comment_map, c);
|
||||
}
|
||||
if let ParagraphChild::Hyperlink(h) = child {
|
||||
if let HyperlinkData::External { rid, path } = h.link.clone() {
|
||||
hyperlink_map.insert(rid, path);
|
||||
};
|
||||
for child in &h.children {
|
||||
if let ParagraphChild::CommentStart(c) = child {
|
||||
self.insert_comment_to_map(&mut comment_map, c);
|
||||
|
@ -619,11 +626,12 @@ impl Docx {
|
|||
}
|
||||
}
|
||||
DocumentChild::Table(table) => {
|
||||
collect_comments_in_table(
|
||||
collect_dependencies_in_table(
|
||||
table,
|
||||
&mut comments,
|
||||
&mut comments_extended,
|
||||
&mut comment_map,
|
||||
&mut hyperlink_map,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -643,6 +651,9 @@ impl Docx {
|
|||
);
|
||||
}
|
||||
if let ParagraphChild::Hyperlink(h) = child {
|
||||
if let HyperlinkData::External { rid, path } = h.link.clone() {
|
||||
hyperlink_map.insert(rid, path);
|
||||
};
|
||||
for child in &h.children {
|
||||
if let ParagraphChild::CommentStart(c) = child {
|
||||
push_comment_and_comment_extended(
|
||||
|
@ -657,11 +668,12 @@ impl Docx {
|
|||
}
|
||||
}
|
||||
DocumentChild::Table(table) => {
|
||||
collect_comments_in_table(
|
||||
collect_dependencies_in_table(
|
||||
table,
|
||||
&mut comments,
|
||||
&mut comments_extended,
|
||||
&mut comment_map,
|
||||
&mut hyperlink_map,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -677,6 +689,10 @@ impl Docx {
|
|||
.add_comments_extended(comments_extended);
|
||||
|
||||
self.comments.add_comments(comments);
|
||||
|
||||
for (id, d) in hyperlink_map {
|
||||
self.document_rels.hyperlinks.push((id, d));
|
||||
}
|
||||
}
|
||||
|
||||
// Traverse and clone comments from document and add to comments node.
|
||||
|
@ -772,11 +788,12 @@ impl Docx {
|
|||
}
|
||||
}
|
||||
|
||||
fn collect_comments_in_table(
|
||||
fn collect_dependencies_in_table(
|
||||
table: &Table,
|
||||
comments: &mut Vec<Comment>,
|
||||
comments_extended: &mut Vec<CommentExtended>,
|
||||
comment_map: &mut HashMap<usize, String>,
|
||||
hyperlink_map: &mut HashMap<String, String>,
|
||||
) {
|
||||
for TableChild::TableRow(row) in &table.rows {
|
||||
for TableRowChild::TableCell(cell) in &row.cells {
|
||||
|
@ -793,6 +810,9 @@ fn collect_comments_in_table(
|
|||
);
|
||||
}
|
||||
if let ParagraphChild::Hyperlink(h) = child {
|
||||
if let HyperlinkData::External { rid, path } = h.link.clone() {
|
||||
hyperlink_map.insert(rid, path);
|
||||
};
|
||||
for child in &h.children {
|
||||
if let ParagraphChild::CommentStart(c) = child {
|
||||
push_comment_and_comment_extended(
|
||||
|
@ -806,9 +826,13 @@ fn collect_comments_in_table(
|
|||
}
|
||||
}
|
||||
}
|
||||
TableCellContent::Table(table) => {
|
||||
collect_comments_in_table(table, comments, comments_extended, comment_map)
|
||||
}
|
||||
TableCellContent::Table(table) => collect_dependencies_in_table(
|
||||
table,
|
||||
comments,
|
||||
comments_extended,
|
||||
comment_map,
|
||||
hyperlink_map,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
use std::io::Read;
|
||||
use std::str::FromStr;
|
||||
|
||||
use xml::attribute::OwnedAttribute;
|
||||
use xml::reader::{EventReader, XmlEvent};
|
||||
|
||||
use super::*;
|
||||
|
||||
use super::attributes::*;
|
||||
|
||||
impl ElementReader for Hyperlink {
|
||||
fn read<R: Read>(
|
||||
r: &mut EventReader<R>,
|
||||
attrs: &[OwnedAttribute],
|
||||
) -> Result<Self, ReaderError> {
|
||||
let mut rid: Option<String> = read(attrs, "id");
|
||||
let mut anchor: Option<String> = read(attrs, "anchor");
|
||||
let history: Option<String> = read(attrs, "history");
|
||||
let mut link = Hyperlink {
|
||||
link: if anchor.is_some() {
|
||||
HyperlinkData::Anchor {
|
||||
anchor: anchor.take().unwrap(),
|
||||
}
|
||||
} else {
|
||||
HyperlinkData::External {
|
||||
rid: rid.take().unwrap_or_default(),
|
||||
path: String::default(), // not used
|
||||
}
|
||||
},
|
||||
history: history.map(|h| usize::from_str(&h).unwrap_or(1)),
|
||||
children: vec![],
|
||||
};
|
||||
|
||||
loop {
|
||||
let e = r.next();
|
||||
match e {
|
||||
Ok(XmlEvent::StartElement {
|
||||
attributes, name, ..
|
||||
}) => {
|
||||
let e = XMLElement::from_str(&name.local_name).unwrap();
|
||||
|
||||
match e {
|
||||
XMLElement::Run => {
|
||||
if let Ok(run) = Run::read(r, attrs) {
|
||||
link = link.add_run(run);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
XMLElement::Insert => {
|
||||
if let Ok(ins) = Insert::read(r, &attributes) {
|
||||
link = link.add_insert(ins);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
XMLElement::Delete => {
|
||||
if let Ok(del) = Delete::read(r, &attributes) {
|
||||
link = link.add_delete(del);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
XMLElement::BookmarkStart => {
|
||||
if let Ok(s) = BookmarkStart::read(r, &attributes) {
|
||||
link = link.add_bookmark_start(s.id, s.name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
XMLElement::BookmarkEnd => {
|
||||
if let Ok(e) = BookmarkEnd::read(r, &attributes) {
|
||||
link = link.add_bookmark_end(e.id);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
XMLElement::CommentRangeStart => {
|
||||
if let Some(id) = read(&attributes, "id") {
|
||||
if let Ok(id) = usize::from_str(&id) {
|
||||
let comment = Comment::new(id);
|
||||
link = link.add_comment_start(comment);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
XMLElement::CommentRangeEnd => {
|
||||
if let Some(id) = read(&attributes, "id") {
|
||||
if let Ok(id) = usize::from_str(&id) {
|
||||
link = link.add_comment_end(id);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Ok(XmlEvent::EndElement { name, .. }) => {
|
||||
let e = XMLElement::from_str(&name.local_name).unwrap();
|
||||
if e == XMLElement::Hyperlink {
|
||||
return Ok(link);
|
||||
}
|
||||
}
|
||||
Err(_) => return Err(ReaderError::XMLReadError),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@ mod comments_extended;
|
|||
mod custom_properties;
|
||||
mod delete;
|
||||
mod div;
|
||||
mod shape;
|
||||
mod doc_defaults;
|
||||
mod doc_grid;
|
||||
mod document;
|
||||
|
@ -22,6 +21,7 @@ mod font_scheme;
|
|||
mod footer;
|
||||
mod from_xml;
|
||||
mod header;
|
||||
mod hyperlink;
|
||||
mod ignore;
|
||||
mod insert;
|
||||
mod instr_text;
|
||||
|
@ -41,6 +41,7 @@ mod run_property;
|
|||
mod section_property;
|
||||
mod settings;
|
||||
mod shading;
|
||||
mod shape;
|
||||
mod structured_data_tag;
|
||||
mod style;
|
||||
mod styles;
|
||||
|
|
|
@ -27,10 +27,15 @@ impl ElementReader for Paragraph {
|
|||
|
||||
match e {
|
||||
XMLElement::Run => {
|
||||
let run = Run::read(r, attrs)?;
|
||||
let run = Run::read(r, &attributes)?;
|
||||
p = p.add_run(run);
|
||||
continue;
|
||||
}
|
||||
XMLElement::Hyperlink => {
|
||||
let link = Hyperlink::read(r, &attributes)?;
|
||||
p = p.add_hyperlink(link);
|
||||
continue;
|
||||
}
|
||||
XMLElement::Insert => {
|
||||
let ins = Insert::read(r, &attributes)?;
|
||||
p = p.add_insert(ins);
|
||||
|
@ -70,7 +75,7 @@ impl ElementReader for Paragraph {
|
|||
}
|
||||
// pPr
|
||||
XMLElement::ParagraphProperty => {
|
||||
if let Ok(pr) = ParagraphProperty::read(r, attrs) {
|
||||
if let Ok(pr) = ParagraphProperty::read(r, &attributes) {
|
||||
p.has_numbering = pr.numbering_property.is_some();
|
||||
p.property = pr;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ pub enum XMLElement {
|
|||
Text,
|
||||
FieldChar,
|
||||
InstrText,
|
||||
Hyperlink,
|
||||
Highlight,
|
||||
VertAlign,
|
||||
Bold,
|
||||
|
@ -240,6 +241,7 @@ impl FromStr for XMLElement {
|
|||
"t" => Ok(XMLElement::Text),
|
||||
"fldChar" => Ok(XMLElement::FieldChar),
|
||||
"instrText" => Ok(XMLElement::InstrText),
|
||||
"hyperlink" => Ok(XMLElement::Hyperlink),
|
||||
"sz" => Ok(XMLElement::Size),
|
||||
"szCs" => Ok(XMLElement::SizeCs),
|
||||
"u" => Ok(XMLElement::Underline),
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
use std::fmt;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use super::errors;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, ts_rs::TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub enum HyperlinkType {
|
||||
Anchor,
|
||||
External,
|
||||
}
|
||||
|
||||
impl fmt::Display for HyperlinkType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
HyperlinkType::Anchor => write!(f, "anchor"),
|
||||
HyperlinkType::External => write!(f, "external"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for HyperlinkType {
|
||||
type Err = errors::TypeError;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"anchor" => Ok(HyperlinkType::Anchor),
|
||||
"external" => Ok(HyperlinkType::External),
|
||||
_ => Ok(HyperlinkType::Anchor),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ pub mod errors;
|
|||
pub mod field_char_type;
|
||||
pub mod font_pitch_type;
|
||||
pub mod height_rule;
|
||||
pub mod hyperlink_type;
|
||||
pub mod level_suffix_type;
|
||||
pub mod line_spacing_type;
|
||||
pub mod page_margin;
|
||||
|
@ -39,6 +40,7 @@ pub use errors::*;
|
|||
pub use field_char_type::*;
|
||||
pub use font_pitch_type::*;
|
||||
pub use height_rule::*;
|
||||
pub use hyperlink_type::*;
|
||||
pub use level_suffix_type::*;
|
||||
pub use line_spacing_type::*;
|
||||
pub use page_margin::*;
|
||||
|
|
|
@ -106,18 +106,18 @@ impl XMLBuilder {
|
|||
mut self,
|
||||
rid: Option<&String>,
|
||||
anchor: Option<&String>,
|
||||
history: bool,
|
||||
history: Option<usize>,
|
||||
) -> Self {
|
||||
let mut e = XmlEvent::start_element("w:hyperlink");
|
||||
let history = history.unwrap_or(1);
|
||||
if let Some(rid) = rid {
|
||||
e = e.attr("w:rid", rid);
|
||||
e = e.attr("r:id", rid);
|
||||
}
|
||||
if let Some(anchor) = anchor {
|
||||
e = e.attr("w:anchor", anchor);
|
||||
}
|
||||
if history {
|
||||
e = e.attr("w:history", "true");
|
||||
}
|
||||
let s = format!("{}", history);
|
||||
e = e.attr("w:history", s.as_str());
|
||||
self.writer.write(e).expect(EXPECT_MESSAGE);
|
||||
self
|
||||
}
|
||||
|
|
|
@ -8,6 +8,14 @@ impl XMLBuilder {
|
|||
|
||||
// Build Relationship
|
||||
closed!(relationship, "Relationship", "Id", "Type", "Target");
|
||||
closed!(
|
||||
relationship_with_mode,
|
||||
"Relationship",
|
||||
"Id",
|
||||
"Type",
|
||||
"Target",
|
||||
"TargetMode"
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
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
|
@ -1,3 +1,5 @@
|
|||
import * as wasm from "./pkg";
|
||||
|
||||
import { Run } from "./run";
|
||||
import { Insert } from "./insert";
|
||||
import { Delete } from "./delete";
|
||||
|
@ -7,12 +9,18 @@ import { Comment } from "./comment";
|
|||
import { CommentEnd } from "./comment-end";
|
||||
import { ParagraphChild } from "./paragraph";
|
||||
|
||||
export type HyperlinkType = "anchor" | "external";
|
||||
|
||||
export class Hyperlink {
|
||||
_rid?: string;
|
||||
_anchor?: string;
|
||||
_history: boolean = false;
|
||||
v: string;
|
||||
type: HyperlinkType;
|
||||
children: ParagraphChild[] = [];
|
||||
|
||||
constructor(v: string, t: HyperlinkType) {
|
||||
this.v = v;
|
||||
this.type = t;
|
||||
}
|
||||
|
||||
addRun(run: Run) {
|
||||
this.children.push(run);
|
||||
return this;
|
||||
|
@ -47,19 +55,11 @@ export class Hyperlink {
|
|||
this.children.push(end);
|
||||
return this;
|
||||
}
|
||||
|
||||
rid(rid: string) {
|
||||
this._rid = rid;
|
||||
return this;
|
||||
}
|
||||
|
||||
anchor(anchor: string) {
|
||||
this._anchor = anchor;
|
||||
return this;
|
||||
}
|
||||
|
||||
history() {
|
||||
this._history = true;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export const convertHyperlinkType = (link: Hyperlink): wasm.HyperlinkType => {
|
||||
if (link.type === "anchor") {
|
||||
return wasm.HyperlinkType.Anchor;
|
||||
}
|
||||
return wasm.HyperlinkType.External;
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Paragraph } from "./paragraph";
|
|||
import { ParagraphProperty } from "./paragraph-property";
|
||||
import { Insert } from "./insert";
|
||||
import { Delete } from "./delete";
|
||||
import { Hyperlink } from "./hyperlink";
|
||||
import { convertHyperlinkType, Hyperlink } from "./hyperlink";
|
||||
import { DeleteText } from "./delete-text";
|
||||
import { Table } from "./table";
|
||||
import { TableOfContents } from "./table-of-contents";
|
||||
|
@ -372,16 +372,7 @@ export class Docx {
|
|||
}
|
||||
|
||||
buildHyperlink(link: Hyperlink) {
|
||||
let hyperlink = wasm.createHyperlink();
|
||||
if (link._history) {
|
||||
hyperlink = hyperlink.history();
|
||||
}
|
||||
if (link._anchor) {
|
||||
hyperlink = hyperlink.anchor(link._anchor);
|
||||
}
|
||||
if (link._rid) {
|
||||
hyperlink = hyperlink.rid(link._rid);
|
||||
}
|
||||
let hyperlink = wasm.createHyperlink(link.v, convertHyperlinkType(link));
|
||||
|
||||
link.children.forEach((child) => {
|
||||
if (child instanceof Run) {
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
export type HyperlinkType = "anchor" | "external";
|
|
@ -4,6 +4,16 @@ import { CommentRangeStartJSON, CommentRangeEndJSON } from "..";
|
|||
import { LineSpacingJSON } from "./line_spacing";
|
||||
|
||||
export type ParagraphChildJSON =
|
||||
| RunJSON
|
||||
| InsertJSON
|
||||
| DeleteJSON
|
||||
| HyperlinkJSON
|
||||
| CommentRangeStartJSON
|
||||
| CommentRangeEndJSON
|
||||
| BookmarkStartJSON
|
||||
| BookmarkEndJSON;
|
||||
|
||||
export type HyperlinkChildJSON =
|
||||
| RunJSON
|
||||
| InsertJSON
|
||||
| DeleteJSON
|
||||
|
@ -69,6 +79,21 @@ export type DeleteJSON = {
|
|||
};
|
||||
};
|
||||
|
||||
export type HyperlinkJSON = {
|
||||
type: "hyperlink";
|
||||
data:
|
||||
| {
|
||||
type: "external";
|
||||
rid: string;
|
||||
children: HyperlinkChildJSON[];
|
||||
history: number | null;
|
||||
}
|
||||
| {
|
||||
type: "anchor";
|
||||
anchor: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type DeleteChildJSON =
|
||||
| RunJSON
|
||||
| CommentRangeStartJSON
|
||||
|
|
|
@ -7,27 +7,12 @@ use super::*;
|
|||
pub struct Hyperlink(docx_rs::Hyperlink);
|
||||
|
||||
#[wasm_bindgen(js_name = createHyperlink)]
|
||||
pub fn create_hyperlink() -> Hyperlink {
|
||||
Hyperlink(docx_rs::Hyperlink::new())
|
||||
pub fn create_hyperlink(v: &str, t: docx_rs::HyperlinkType) -> Hyperlink {
|
||||
Hyperlink(docx_rs::Hyperlink::new(v, t))
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Hyperlink {
|
||||
pub fn rid(mut self, rid: &str) -> Self {
|
||||
self.0 = self.0.rid(rid);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn anchor(mut self, anchor: &str) -> Self {
|
||||
self.0 = self.0.anchor(anchor);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn history(mut self) -> Self {
|
||||
self.0 = self.0.history();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_run(mut self, run: Run) -> Self {
|
||||
self.0 = self.0.add_run(run.take());
|
||||
self
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -153,6 +153,12 @@ describe("reader", () => {
|
|||
const json = w.readDocx(buffer);
|
||||
expect(json).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("should read hyperlink", () => {
|
||||
const buffer = readFileSync("../fixtures/link/link.docx");
|
||||
const json = w.readDocx(buffer);
|
||||
expect(json).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe("writer", () => {
|
||||
|
@ -518,9 +524,9 @@ describe("writer", () => {
|
|||
}
|
||||
});
|
||||
|
||||
test("should write hyperlink", () => {
|
||||
test("should write anchor hyperlink", () => {
|
||||
const p1 = new w.Paragraph().addHyperlink(
|
||||
new w.Hyperlink().anchor("anchor").addRun(new w.Run().addText("Hello!!"))
|
||||
new w.Hyperlink("anchor", "anchor").addRun(new w.Run().addText("Hello!!"))
|
||||
);
|
||||
const p2 = new w.Paragraph()
|
||||
.addBookmarkStart(1, "anchor")
|
||||
|
@ -529,7 +535,24 @@ describe("writer", () => {
|
|||
.addBookmarkEnd(1);
|
||||
const buffer = new w.Docx().addParagraph(p1).addParagraph(p2).build();
|
||||
|
||||
writeFileSync("../output/js/hyperlink.docx", buffer);
|
||||
writeFileSync("../output/js/anchor-hyperlink.docx", buffer);
|
||||
const z = new Zip(Buffer.from(buffer));
|
||||
for (const e of z.getEntries()) {
|
||||
if (e.entryName.match(/document.xml/)) {
|
||||
expect(z.readAsText(e)).toMatchSnapshot();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("should write external hyperlink", () => {
|
||||
const p1 = new w.Paragraph().addHyperlink(
|
||||
new w.Hyperlink("https://example.com", "external").addRun(
|
||||
new w.Run().addText("Hello!!")
|
||||
)
|
||||
);
|
||||
const buffer = new w.Docx().addParagraph(p1).build();
|
||||
|
||||
writeFileSync("../output/js/external-hyperlink.docx", buffer);
|
||||
const z = new Zip(Buffer.from(buffer));
|
||||
for (const e of z.getEntries()) {
|
||||
if (e.entryName.match(/document.xml/)) {
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/><Override PartName="/word/webSettings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"/><Override PartName="/word/fontTable.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"/><Override PartName="/word/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/></Types>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><Template>Normal.dotm</Template><TotalTime>1</TotalTime><Pages>1</Pages><Words>6</Words><Characters>37</Characters><Application>Microsoft Office Word</Application><DocSecurity>0</DocSecurity><Lines>1</Lines><Paragraphs>1</Paragraphs><ScaleCrop>false</ScaleCrop><Company></Company><LinksUpToDate>false</LinksUpToDate><CharactersWithSpaces>42</CharactersWithSpaces><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>16.0000</AppVersion></Properties>
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:dcterms="http://purl.org/dc/terms/"
|
||||
xmlns:dcmitype="http://purl.org/dc/dcmitype/"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<dc:title></dc:title>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>bokuweb</dc:creator>
|
||||
<cp:keywords></cp:keywords>
|
||||
<dc:description></dc:description>
|
||||
<cp:lastModifiedBy>bokuweb</cp:lastModifiedBy>
|
||||
<cp:revision>1</cp:revision>
|
||||
<dcterms:created xsi:type="dcterms:W3CDTF">2022-06-30T14:30:00Z</dcterms:created>
|
||||
<dcterms:modified xsi:type="dcterms:W3CDTF">2022-06-30T14:31:00Z</dcterms:modified>
|
||||
</cp:coreProperties>
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/><Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/><Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="https://google.com/" TargetMode="External"/></Relationships>
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"
|
||||
xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex"
|
||||
xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex"
|
||||
xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex"
|
||||
xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex"
|
||||
xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex"
|
||||
xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex"
|
||||
xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex"
|
||||
xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex"
|
||||
xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink"
|
||||
xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d"
|
||||
xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:oel="http://schemas.microsoft.com/office/2019/extlst"
|
||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
|
||||
xmlns:v="urn:schemas-microsoft-com:vml"
|
||||
xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"
|
||||
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
|
||||
xmlns:w10="urn:schemas-microsoft-com:office:word"
|
||||
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
|
||||
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"
|
||||
xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex"
|
||||
xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid"
|
||||
xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml"
|
||||
xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash"
|
||||
xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex"
|
||||
xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"
|
||||
xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk"
|
||||
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
|
||||
xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14">
|
||||
<w:body>
|
||||
<w:p w14:paraId="6B7AF587" w14:textId="1D3B7D02" w:rsidR="00125C12" w:rsidRDefault="004E7262">
|
||||
<w:hyperlink r:id="rId4">
|
||||
<w:r w:rsidRPr="004E7262">
|
||||
<w:rPr>
|
||||
</w:rPr>
|
||||
<w:t>Hello</w:t>
|
||||
</w:r>
|
||||
</w:hyperlink>
|
||||
<w:r>
|
||||
<w:t>o</w:t>
|
||||
</w:r>
|
||||
</w:p>
|
||||
<w:sectPr w:rsidR="00125C12">
|
||||
<w:pgSz w:w="11906" w:h="16838"/>
|
||||
<w:pgMar w:top="1985" w:right="1701" w:bottom="1701" w:left="1701" w:header="851" w:footer="992" w:gutter="0"/>
|
||||
<w:cols w:space="425"/>
|
||||
<w:docGrid w:type="lines" w:linePitch="360"/>
|
||||
</w:sectPr>
|
||||
</w:body>
|
||||
</w:document>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<w:fonts xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh"><w:font w:name="游明朝"><w:panose1 w:val="02020400000000000000"/><w:charset w:val="80"/><w:family w:val="roman"/><w:pitch w:val="variable"/><w:sig w:usb0="800002E7" w:usb1="2AC7FCFF" w:usb2="00000012" w:usb3="00000000" w:csb0="0002009F" w:csb1="00000000"/></w:font><w:font w:name="Times New Roman"><w:panose1 w:val="02020603050405020304"/><w:charset w:val="00"/><w:family w:val="roman"/><w:pitch w:val="variable"/><w:sig w:usb0="E0002EFF" w:usb1="C000785B" w:usb2="00000009" w:usb3="00000000" w:csb0="000001FF" w:csb1="00000000"/></w:font><w:font w:name="游ゴシック Light"><w:panose1 w:val="020B0300000000000000"/><w:charset w:val="80"/><w:family w:val="swiss"/><w:pitch w:val="variable"/><w:sig w:usb0="E00002FF" w:usb1="2AC7FDFF" w:usb2="00000016" w:usb3="00000000" w:csb0="0002009F" w:csb1="00000000"/></w:font></w:fonts>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<w:settings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh"><w:zoom w:percent="224"/><w:doNotDisplayPageBoundaries/><w:bordersDoNotSurroundHeader/><w:bordersDoNotSurroundFooter/><w:proofState w:grammar="clean"/><w:defaultTabStop w:val="840"/><w:displayHorizontalDrawingGridEvery w:val="0"/><w:displayVerticalDrawingGridEvery w:val="2"/><w:characterSpacingControl w:val="compressPunctuation"/><w:compat><w:spaceForUL/><w:balanceSingleByteDoubleByteWidth/><w:doNotLeaveBackslashAlone/><w:ulTrailSpace/><w:doNotExpandShiftReturn/><w:adjustLineHeightInTable/><w:useFELayout/><w:compatSetting w:name="compatibilityMode" w:uri="http://schemas.microsoft.com/office/word" w:val="15"/><w:compatSetting w:name="overrideTableStyleFontSizeAndJustification" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="enableOpenTypeFeatures" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="doNotFlipMirrorIndents" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="differentiateMultirowTableHeaders" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="useWord2013TrackBottomHyphenation" w:uri="http://schemas.microsoft.com/office/word" w:val="0"/></w:compat><w:rsids><w:rsidRoot w:val="004E7262"/><w:rsid w:val="00125C12"/><w:rsid w:val="004E7262"/><w:rsid w:val="00B26F0E"/><w:rsid w:val="00CE04E0"/></w:rsids><m:mathPr><m:mathFont m:val="Cambria Math"/><m:brkBin m:val="before"/><m:brkBinSub m:val="--"/><m:smallFrac m:val="0"/><m:dispDef/><m:lMargin m:val="0"/><m:rMargin m:val="0"/><m:defJc m:val="centerGroup"/><m:wrapIndent m:val="1440"/><m:intLim m:val="subSup"/><m:naryLim m:val="undOvr"/></m:mathPr><w:themeFontLang w:val="en-US" w:eastAsia="ja-JP"/><w:clrSchemeMapping w:bg1="light1" w:t1="dark1" w:bg2="light2" w:t2="dark2" w:accent1="accent1" w:accent2="accent2" w:accent3="accent3" w:accent4="accent4" w:accent5="accent5" w:accent6="accent6" w:hyperlink="hyperlink" w:followedHyperlink="followedHyperlink"/><w:decimalSymbol w:val="."/><w:listSeparator w:val=","/><w14:docId w14:val="55AA446F"/><w15:chartTrackingRefBased/><w15:docId w15:val="{B1317C39-ACCF-5B4D-BE97-FD2D73F14B00}"/></w:settings>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<w:webSettings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh"><w:optimizeForBrowser/><w:allowPNG/></w:webSettings>
|
Loading…
Reference in New Issue