parent
b8ad56daab
commit
a4ddb3a5ee
|
@ -0,0 +1,67 @@
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use crate::documents::*;
|
||||||
|
|
||||||
|
// https://c-rex.net/projects/samples/ooxml/e1/Part4/OOXML_P4_DOCX_PAGEREFPAGEREF_topic_ID0EHXK1.html
|
||||||
|
#[derive(Serialize, Debug, Clone, PartialEq, Default)]
|
||||||
|
pub struct InstrPAGEREF {
|
||||||
|
pub page_ref: String,
|
||||||
|
pub hyperlink: bool,
|
||||||
|
pub relative_position: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InstrPAGEREF {
|
||||||
|
pub fn new(r: impl Into<String>) -> Self {
|
||||||
|
Self {
|
||||||
|
page_ref: r.into(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hyperlink(mut self) -> Self {
|
||||||
|
self.hyperlink = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn relative_position(mut self) -> Self {
|
||||||
|
self.relative_position = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuildXML for InstrPAGEREF {
|
||||||
|
fn build(&self) -> Vec<u8> {
|
||||||
|
let mut instr = format!("PAGEREF {}", self.page_ref);
|
||||||
|
|
||||||
|
if self.relative_position {
|
||||||
|
instr = format!("{} \\p", instr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.hyperlink {
|
||||||
|
instr = format!("{} \\h", instr);
|
||||||
|
}
|
||||||
|
|
||||||
|
instr.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for InstrPAGEREF {
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
fn from_str(instr: &str) -> Result<Self, Self::Err> {
|
||||||
|
let mut s = instr.split(' ');
|
||||||
|
let text = s.next();
|
||||||
|
let mut page_ref = InstrPAGEREF::new(text.unwrap_or_default());
|
||||||
|
loop {
|
||||||
|
if let Some(i) = s.next() {
|
||||||
|
match i {
|
||||||
|
"\\h" => page_ref = page_ref.hyperlink(),
|
||||||
|
"\\p" => page_ref = page_ref.relative_position(),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Ok(page_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use crate::documents::*;
|
||||||
|
|
||||||
|
// https://c-rex.net/projects/samples/ooxml/e1/Part4/OOXML_P4_DOCX_TCTC_topic_ID0EU2N1.html
|
||||||
|
#[derive(Serialize, Debug, Clone, PartialEq, Default)]
|
||||||
|
pub struct InstrTC {
|
||||||
|
pub text: String,
|
||||||
|
// \n Omits the page number for the entry.
|
||||||
|
pub omits_page_number: bool,
|
||||||
|
pub level: Option<usize>,
|
||||||
|
// \f
|
||||||
|
pub item_type_identifier: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InstrTC {
|
||||||
|
pub fn new(text: impl Into<String>) -> Self {
|
||||||
|
Self {
|
||||||
|
text: text.into(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn omits_page_number(mut self) -> Self {
|
||||||
|
self.omits_page_number = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn level(mut self, level: usize) -> Self {
|
||||||
|
self.level = Some(level);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn item_type_identifier(mut self, t: impl Into<String>) -> Self {
|
||||||
|
self.item_type_identifier = Some(t.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuildXML for InstrTC {
|
||||||
|
fn build(&self) -> Vec<u8> {
|
||||||
|
let mut instr = format!("TC {}", self.text);
|
||||||
|
|
||||||
|
if let Some(ref t) = self.item_type_identifier {
|
||||||
|
instr = format!("{} \\f {}", instr, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(level) = self.level {
|
||||||
|
instr = format!("{} \\l {}", instr, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.omits_page_number {
|
||||||
|
instr = format!("{} \\n", instr);
|
||||||
|
}
|
||||||
|
|
||||||
|
instr.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_level(i: &str) -> Option<usize> {
|
||||||
|
let r = i.replace(""", "").replace("\"", "");
|
||||||
|
if let Ok(l) = usize::from_str(&r) {
|
||||||
|
return Some(l);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for InstrTC {
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
fn from_str(instr: &str) -> Result<Self, Self::Err> {
|
||||||
|
let mut s = instr.split(' ');
|
||||||
|
let text = s.next();
|
||||||
|
let mut tc = InstrTC::new(text.unwrap_or_default());
|
||||||
|
loop {
|
||||||
|
if let Some(i) = s.next() {
|
||||||
|
match i {
|
||||||
|
"\\f" => {
|
||||||
|
if let Some(r) = s.next() {
|
||||||
|
let r = r.replace(""", "").replace("\"", "");
|
||||||
|
tc = tc.item_type_identifier(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"\\l" => {
|
||||||
|
if let Some(r) = s.next() {
|
||||||
|
if let Some(l) = parse_level(r) {
|
||||||
|
tc = tc.level(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"\\n" => tc = tc.omits_page_number(),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Ok(tc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,8 @@ use crate::xml_builder::*;
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum InstrText {
|
pub enum InstrText {
|
||||||
TOC(InstrToC),
|
TOC(InstrToC),
|
||||||
|
TC(InstrTC),
|
||||||
|
PAGEREF(InstrPAGEREF),
|
||||||
Unsupported(String),
|
Unsupported(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +16,8 @@ impl BuildXML for Box<InstrText> {
|
||||||
fn build(&self) -> Vec<u8> {
|
fn build(&self) -> Vec<u8> {
|
||||||
let instr = match self.as_ref() {
|
let instr = match self.as_ref() {
|
||||||
InstrText::TOC(toc) => toc.build(),
|
InstrText::TOC(toc) => toc.build(),
|
||||||
|
InstrText::TC(tc) => tc.build(),
|
||||||
|
InstrText::PAGEREF(page_ref) => page_ref.build(),
|
||||||
InstrText::Unsupported(s) => s.as_bytes().to_vec(),
|
InstrText::Unsupported(s) => s.as_bytes().to_vec(),
|
||||||
};
|
};
|
||||||
XMLBuilder::new()
|
XMLBuilder::new()
|
||||||
|
@ -36,6 +40,18 @@ impl Serialize for InstrText {
|
||||||
t.serialize_field("data", s)?;
|
t.serialize_field("data", s)?;
|
||||||
t.end()
|
t.end()
|
||||||
}
|
}
|
||||||
|
InstrText::TC(ref s) => {
|
||||||
|
let mut t = serializer.serialize_struct("TC", 2)?;
|
||||||
|
t.serialize_field("type", "tc")?;
|
||||||
|
t.serialize_field("data", s)?;
|
||||||
|
t.end()
|
||||||
|
}
|
||||||
|
InstrText::PAGEREF(ref s) => {
|
||||||
|
let mut t = serializer.serialize_struct("PAGEREF", 2)?;
|
||||||
|
t.serialize_field("type", "pageref")?;
|
||||||
|
t.serialize_field("data", s)?;
|
||||||
|
t.end()
|
||||||
|
}
|
||||||
InstrText::Unsupported(ref s) => {
|
InstrText::Unsupported(ref s) => {
|
||||||
let mut t = serializer.serialize_struct("Unsupported", 2)?;
|
let mut t = serializer.serialize_struct("Unsupported", 2)?;
|
||||||
t.serialize_field("type", "unsupported")?;
|
t.serialize_field("type", "unsupported")?;
|
||||||
|
@ -62,4 +78,16 @@ mod tests {
|
||||||
r#"<w:instrText>TOC \o "1-3"</w:instrText>"#
|
r#"<w:instrText>TOC \o "1-3"</w:instrText>"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_pageref_instr() {
|
||||||
|
let b = Box::new(InstrText::PAGEREF(
|
||||||
|
InstrPAGEREF::new("_Toc90425847").hyperlink(),
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
assert_eq!(
|
||||||
|
str::from_utf8(&b).unwrap(),
|
||||||
|
r#"<w:instrText>PAGEREF _Toc90425847 \h</w:instrText>"#
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ mod default_tab_stop;
|
||||||
mod delete;
|
mod delete;
|
||||||
mod delete_text;
|
mod delete_text;
|
||||||
mod div;
|
mod div;
|
||||||
mod instr_toc;
|
|
||||||
mod doc_defaults;
|
mod doc_defaults;
|
||||||
mod doc_grid;
|
mod doc_grid;
|
||||||
mod doc_id;
|
mod doc_id;
|
||||||
|
@ -33,7 +32,10 @@ mod highlight;
|
||||||
mod indent;
|
mod indent;
|
||||||
mod indent_level;
|
mod indent_level;
|
||||||
mod insert;
|
mod insert;
|
||||||
|
mod instr_pageref;
|
||||||
|
mod instr_tc;
|
||||||
mod instr_text;
|
mod instr_text;
|
||||||
|
mod instr_toc;
|
||||||
mod italic;
|
mod italic;
|
||||||
mod italic_cs;
|
mod italic_cs;
|
||||||
mod justification;
|
mod justification;
|
||||||
|
@ -136,7 +138,10 @@ pub use highlight::*;
|
||||||
pub use indent::*;
|
pub use indent::*;
|
||||||
pub use indent_level::*;
|
pub use indent_level::*;
|
||||||
pub use insert::*;
|
pub use insert::*;
|
||||||
|
pub use instr_pageref::*;
|
||||||
|
pub use instr_tc::*;
|
||||||
pub use instr_text::*;
|
pub use instr_text::*;
|
||||||
|
pub use instr_toc::*;
|
||||||
pub use italic::*;
|
pub use italic::*;
|
||||||
pub use italic_cs::*;
|
pub use italic_cs::*;
|
||||||
pub use justification::*;
|
pub use justification::*;
|
||||||
|
@ -204,4 +209,3 @@ pub use wp_anchor::*;
|
||||||
pub use wps_shape::*;
|
pub use wps_shape::*;
|
||||||
pub use wps_text_box::*;
|
pub use wps_text_box::*;
|
||||||
pub use zoom::*;
|
pub use zoom::*;
|
||||||
pub use instr_toc::*;
|
|
||||||
|
|
|
@ -29,10 +29,19 @@ impl ElementReader for InstrText {
|
||||||
return Err(ReaderError::XMLReadError);
|
return Err(ReaderError::XMLReadError);
|
||||||
} else {
|
} else {
|
||||||
if instr.starts_with("TOC") {
|
if instr.starts_with("TOC") {
|
||||||
for i in instr.split(' ') {
|
if let Ok(instr) = InstrToC::from_str(instr) {
|
||||||
dbg!(i);
|
return Ok(InstrText::TOC(instr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if instr.starts_with("TC") {
|
||||||
|
if let Ok(instr) = InstrTC::from_str(instr) {
|
||||||
|
return Ok(InstrText::TC(instr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if instr.starts_with("PAGEREF") {
|
||||||
|
if let Ok(instr) = InstrPAGEREF::from_str(instr) {
|
||||||
|
return Ok(InstrText::PAGEREF(instr));
|
||||||
}
|
}
|
||||||
return Ok(InstrText::TOC(InstrToC::new()));
|
|
||||||
}
|
}
|
||||||
return Ok(InstrText::Unsupported(instr.to_string()));
|
return Ok(InstrText::Unsupported(instr.to_string()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -23126,15 +23126,19 @@ Object {
|
||||||
"caption_label_including_numbers": null,
|
"caption_label_including_numbers": null,
|
||||||
"entry_and_page_number_separator": null,
|
"entry_and_page_number_separator": null,
|
||||||
"entry_bookmark_name": null,
|
"entry_bookmark_name": null,
|
||||||
"hide_tab_and_page_numbers_in_webview": false,
|
"heading_styles_range": Array [
|
||||||
"hyperlink": false,
|
1,
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
"hide_tab_and_page_numbers_in_webview": true,
|
||||||
|
"hyperlink": true,
|
||||||
"preserve_new_line": false,
|
"preserve_new_line": false,
|
||||||
"preserve_tab": false,
|
"preserve_tab": false,
|
||||||
"seq_field_identifier_for_prefix": null,
|
"seq_field_identifier_for_prefix": null,
|
||||||
"sequence_and_page_numbers_separator": null,
|
"sequence_and_page_numbers_separator": null,
|
||||||
"styles_with_levels": Array [],
|
"styles_with_levels": Array [],
|
||||||
"tc_field_identifier": null,
|
"tc_field_identifier": null,
|
||||||
"use_applied_paragraph_line_level": false,
|
"use_applied_paragraph_line_level": true,
|
||||||
},
|
},
|
||||||
"type": "toc",
|
"type": "toc",
|
||||||
},
|
},
|
||||||
|
@ -23351,8 +23355,12 @@ Object {
|
||||||
"children": Array [
|
"children": Array [
|
||||||
Object {
|
Object {
|
||||||
"data": Object {
|
"data": Object {
|
||||||
"data": "PAGEREF _Toc89816785 \\\\h",
|
"data": Object {
|
||||||
"type": "unsupported",
|
"hyperlink": true,
|
||||||
|
"page_ref": "PAGEREF",
|
||||||
|
"relative_position": false,
|
||||||
|
},
|
||||||
|
"type": "pageref",
|
||||||
},
|
},
|
||||||
"type": "instrText",
|
"type": "instrText",
|
||||||
},
|
},
|
||||||
|
@ -23695,8 +23703,12 @@ Object {
|
||||||
"children": Array [
|
"children": Array [
|
||||||
Object {
|
Object {
|
||||||
"data": Object {
|
"data": Object {
|
||||||
"data": "PAGEREF _Toc89816786 \\\\h",
|
"data": Object {
|
||||||
"type": "unsupported",
|
"hyperlink": true,
|
||||||
|
"page_ref": "PAGEREF",
|
||||||
|
"relative_position": false,
|
||||||
|
},
|
||||||
|
"type": "pageref",
|
||||||
},
|
},
|
||||||
"type": "instrText",
|
"type": "instrText",
|
||||||
},
|
},
|
||||||
|
@ -24039,8 +24051,12 @@ Object {
|
||||||
"children": Array [
|
"children": Array [
|
||||||
Object {
|
Object {
|
||||||
"data": Object {
|
"data": Object {
|
||||||
"data": "PAGEREF _Toc89816787 \\\\h",
|
"data": Object {
|
||||||
"type": "unsupported",
|
"hyperlink": true,
|
||||||
|
"page_ref": "PAGEREF",
|
||||||
|
"relative_position": false,
|
||||||
|
},
|
||||||
|
"type": "pageref",
|
||||||
},
|
},
|
||||||
"type": "instrText",
|
"type": "instrText",
|
||||||
},
|
},
|
||||||
|
@ -24383,8 +24399,12 @@ Object {
|
||||||
"children": Array [
|
"children": Array [
|
||||||
Object {
|
Object {
|
||||||
"data": Object {
|
"data": Object {
|
||||||
"data": "PAGEREF _Toc89816788 \\\\h",
|
"data": Object {
|
||||||
"type": "unsupported",
|
"hyperlink": true,
|
||||||
|
"page_ref": "PAGEREF",
|
||||||
|
"relative_position": false,
|
||||||
|
},
|
||||||
|
"type": "pageref",
|
||||||
},
|
},
|
||||||
"type": "instrText",
|
"type": "instrText",
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue