feat: Support pageNumType (#684)

* fix: support page num type writer

* fix: read page num type

* fix: add json type

* fix: add page num type writer

* 0.4.12-beta0

* fix

* fix
main
bokuweb 2024-03-06 19:13:11 +09:00 committed by GitHub
parent 8f79032765
commit 9fbd323ce7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
41 changed files with 205 additions and 26 deletions

View File

@ -228,6 +228,11 @@ impl Document {
self.section_property.text_direction = direction; self.section_property.text_direction = direction;
self self
} }
pub fn page_num_type(mut self, p: PageNumType) -> Self {
self.section_property = self.section_property.page_num_type(p);
self
}
} }
impl BuildXML for DocumentChild { impl BuildXML for DocumentChild {

View File

@ -61,6 +61,7 @@ mod numbering_id;
mod numbering_property; mod numbering_property;
mod outline_lvl; mod outline_lvl;
mod page_margin; mod page_margin;
mod page_num_type;
mod page_size; mod page_size;
mod paragraph; mod paragraph;
mod paragraph_borders; mod paragraph_borders;
@ -185,6 +186,7 @@ pub use numbering_id::*;
pub use numbering_property::*; pub use numbering_property::*;
pub use outline_lvl::*; pub use outline_lvl::*;
pub use page_margin::*; pub use page_margin::*;
pub use page_num_type::*;
pub use page_size::*; pub use page_size::*;
pub use paragraph::*; pub use paragraph::*;
pub use paragraph_borders::*; pub use paragraph_borders::*;

View File

@ -0,0 +1,42 @@
use crate::documents::BuildXML;
use crate::xml_builder::*;
use serde::Serialize;
#[derive(Debug, Clone, PartialEq, Serialize, Default)]
#[cfg_attr(feature = "wasm", derive(ts_rs::TS))]
#[cfg_attr(feature = "wasm", ts(export))]
#[serde(rename_all = "camelCase")]
pub struct PageNumType {
#[serde(skip_serializing_if = "Option::is_none")]
pub start: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub chap_style: Option<String>,
}
impl PageNumType {
pub fn new() -> Self {
Default::default()
}
pub fn start(self, s: u32) -> Self {
Self {
start: Some(s),
..self
}
}
pub fn chap_style(self, s: impl Into<String>) -> Self {
Self {
chap_style: Some(s.into()),
..self
}
}
}
impl BuildXML for PageNumType {
fn build(&self) -> Vec<u8> {
XMLBuilder::new()
.page_num_type(self.start, self.chap_style.clone())
.build()
}
}

View File

@ -43,6 +43,8 @@ pub struct SectionProperty {
pub even_footer: Option<Footer>, pub even_footer: Option<Footer>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub section_type: Option<SectionType>, pub section_type: Option<SectionType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page_num_type: Option<PageNumType>,
} }
impl SectionProperty { impl SectionProperty {
@ -157,6 +159,11 @@ impl SectionProperty {
} }
footers footers
} }
pub fn page_num_type(mut self, h: PageNumType) -> Self {
self.page_num_type = Some(h);
self
}
} }
impl Default for SectionProperty { impl Default for SectionProperty {
@ -184,6 +191,7 @@ impl Default for SectionProperty {
even_footer_reference: None, even_footer_reference: None,
even_footer: None, even_footer: None,
section_type: None, section_type: None,
page_num_type: None,
} }
} }
} }
@ -202,7 +210,9 @@ impl BuildXML for SectionProperty {
.add_optional_child(&self.even_header_reference) .add_optional_child(&self.even_header_reference)
.add_optional_child(&self.footer_reference) .add_optional_child(&self.footer_reference)
.add_optional_child(&self.first_footer_reference) .add_optional_child(&self.first_footer_reference)
.add_optional_child(&self.even_footer_reference); .add_optional_child(&self.even_footer_reference)
.add_optional_child(&self.page_num_type);
if !self.text_direction.eq("lrTb") { if !self.text_direction.eq("lrTb") {
b = b.text_direction(&self.text_direction); b = b.text_direction(&self.text_direction);
} }

View File

@ -505,6 +505,11 @@ impl Docx {
self self
} }
pub fn page_num_type(mut self, p: PageNumType) -> Self {
self.document = self.document.page_num_type(p);
self
}
pub fn build(mut self) -> XMLDocx { pub fn build(mut self) -> XMLDocx {
self.reset(); self.reset();

View File

@ -30,6 +30,7 @@ mod level_override;
mod mc_fallback; mod mc_fallback;
mod numbering_property; mod numbering_property;
mod numberings; mod numberings;
mod page_num_type;
mod paragraph; mod paragraph;
mod paragraph_property; mod paragraph_property;
mod paragraph_property_change; mod paragraph_property_change;
@ -358,7 +359,9 @@ pub fn read_docx(buf: &[u8]) -> Result<Docx, ReaderError> {
.clone() .clone()
{ {
if let Some((footer, rels)) = footers.get(&f.id) { if let Some((footer, rels)) = footers.get(&f.id) {
docx.document = docx.document.first_footer_without_title_pg(footer.clone(), &f.id); docx.document = docx
.document
.first_footer_without_title_pg(footer.clone(), &f.id);
let count = docx.document_rels.footer_count + 1; let count = docx.document_rels.footer_count + 1;
docx.document_rels.footer_count = count; docx.document_rels.footer_count = count;
docx.content_type = docx.content_type.add_footer(); docx.content_type = docx.content_type.add_footer();

View File

@ -0,0 +1,27 @@
use std::io::Read;
use std::str::FromStr;
use xml::attribute::OwnedAttribute;
use xml::reader::EventReader;
use super::*;
impl ElementReader for PageNumType {
fn read<R: Read>(
_r: &mut EventReader<R>,
attrs: &[OwnedAttribute],
) -> Result<Self, ReaderError> {
let mut p = PageNumType::new();
for a in attrs {
let local_name = &a.name.local_name;
if local_name == "start" {
if let Ok(s) = u32::from_str(&a.value) {
p = p.start(s);
}
} else if local_name == "chapStyle" {
p = p.chap_style(a.value.clone());
}
}
Ok(p)
}
}

View File

@ -106,6 +106,11 @@ impl ElementReader for SectionProperty {
sp = sp.doc_grid(doc_grid); sp = sp.doc_grid(doc_grid);
} }
} }
XMLElement::PageNumType => {
if let Ok(page_num_type) = PageNumType::read(r, &attributes) {
sp = sp.page_num_type(page_num_type);
}
}
XMLElement::HeaderReference => { XMLElement::HeaderReference => {
if let Ok((rid, header_type)) = if let Ok((rid, header_type)) =
read_header_or_footer_reference(&attributes) read_header_or_footer_reference(&attributes)

View File

@ -158,6 +158,7 @@ pub enum XMLElement {
EvenAndOddHeaders, EvenAndOddHeaders,
StructuredDataTag, StructuredDataTag,
Type, Type,
PageNumType,
Unsupported, Unsupported,
} }
@ -390,6 +391,7 @@ impl FromStr for XMLElement {
"titlePg" => Ok(XMLElement::TitlePg), "titlePg" => Ok(XMLElement::TitlePg),
"evenAndOddHeaders" => Ok(XMLElement::EvenAndOddHeaders), "evenAndOddHeaders" => Ok(XMLElement::EvenAndOddHeaders),
"sdt" => Ok(XMLElement::StructuredDataTag), "sdt" => Ok(XMLElement::StructuredDataTag),
"pgNumType" => Ok(XMLElement::PageNumType),
"type" => Ok(XMLElement::Type), "type" => Ok(XMLElement::Type),
_ => Ok(XMLElement::Unsupported), _ => Ok(XMLElement::Unsupported),
} }

View File

@ -447,7 +447,11 @@ impl XMLBuilder {
closed!(ul_trail_space, "w:ulTrailSpace"); closed!(ul_trail_space, "w:ulTrailSpace");
closed!(do_not_expand_shift_return, "w:doNotExpandShiftReturn"); closed!(do_not_expand_shift_return, "w:doNotExpandShiftReturn");
closed!(adjust_line_height_table, "w:adjustLineHeightInTable"); closed!(adjust_line_height_table, "w:adjustLineHeightInTable");
closed!(character_spacing_control,"w:characterSpacingControl","w:val"); closed!(
character_spacing_control,
"w:characterSpacingControl",
"w:val"
);
closed!(use_fe_layout, "w:useFELayout"); closed!(use_fe_layout, "w:useFELayout");
closed!( closed!(
compat_setting, compat_setting,
@ -563,6 +567,20 @@ impl XMLBuilder {
self.close() self.close()
} }
pub(crate) fn page_num_type(mut self, start: Option<u32>, chap_style: Option<String>) -> Self {
let mut w = XmlEvent::start_element("w:pgNumType");
let start_string = format!("{}", start.unwrap_or_default());
let chap_style_string = chap_style.clone().unwrap_or_default();
if start.is_some() {
w = w.attr("w:start", &start_string);
}
if chap_style.is_some() {
w = w.attr("w:chapStyle", &chap_style_string);
}
self.writer.write(w).expect(EXPECT_MESSAGE);
self.close()
}
pub(crate) fn tab( pub(crate) fn tab(
mut self, mut self,
v: Option<TabValueType>, v: Option<TabValueType>,

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

@ -517,6 +517,12 @@ export class Docx {
} }
} }
if (this.sectionProperty._pageTypeNum) {
const { start, chapStyle } = this.sectionProperty._pageTypeNum;
const p = wasm.createPageNumType(start, chapStyle);
docx = docx.page_num_type(p);
}
if (this.sectionProperty._docGrid) { if (this.sectionProperty._docGrid) {
const { gridType, charSpace, linePitch } = this.sectionProperty._docGrid; const { gridType, charSpace, linePitch } = this.sectionProperty._docGrid;
let type = wasm.DocGridType.Default; let type = wasm.DocGridType.Default;

View File

@ -0,0 +1,2 @@
export interface PageNumType { start?: number, chapStyle?: string, }

View File

@ -1,5 +1,8 @@
import { HeaderJSON, HeaderReferenceJSON } from "./header"; import { HeaderJSON, HeaderReferenceJSON } from "./header";
import { FooterJSON, FooterReferenceJSON } from "./footer"; import { FooterJSON, FooterReferenceJSON } from "./footer";
import { PageNumType as PageNumTypeJSON } from "./bindings/PageNumType";
export { PageNumType as PageNumTypeJSON } from "./bindings/PageNumType";
export type DocGridType = "default" | "lines" | "linesAndChars" | "snapToChars"; export type DocGridType = "default" | "lines" | "linesAndChars" | "snapToChars";
@ -48,4 +51,5 @@ export type SectionPropertyJSON = {
firstFooter?: FooterJSON; firstFooter?: FooterJSON;
evenFooterReference?: FooterReferenceJSON; evenFooterReference?: FooterReferenceJSON;
evenFooter?: FooterJSON; evenFooter?: FooterJSON;
pageNumType?: PageNumTypeJSON;
}; };

View File

@ -1,6 +1,7 @@
import { DocGridType } from "."; import { DocGridType } from ".";
import { Footer } from "./footer"; import { Footer } from "./footer";
import { Header } from "./header"; import { Header } from "./header";
import { PageNumType } from "./json/bindings/PageNumType";
export type DocGrid = { export type DocGrid = {
gridType: DocGridType; gridType: DocGridType;
@ -21,6 +22,7 @@ export class SectionProperty {
_footer: Footer | null = null; _footer: Footer | null = null;
_firstFooter: Footer | null = null; _firstFooter: Footer | null = null;
_evenFooter: Footer | null = null; _evenFooter: Footer | null = null;
_pageTypeNum: PageNumType | null = null;
pageSize(w: number, h: number) { pageSize(w: number, h: number) {
this._pageSize.w = w; this._pageSize.w = w;
@ -72,6 +74,11 @@ export class SectionProperty {
this._evenFooter = footer; this._evenFooter = footer;
return this; return this;
} }
pageTypeNum({ start, chapStyle }: { start: number; chapStyle: string }) {
this._pageTypeNum = { start, chapStyle };
return this;
}
} }
export type PageOrientationType = "landscape" | "portrait"; export type PageOrientationType = "landscape" | "portrait";

View File

@ -1,6 +1,6 @@
{ {
"name": "docx-wasm", "name": "docx-wasm",
"version": "0.4.11", "version": "0.4.12-beta1",
"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

@ -178,6 +178,11 @@ impl Docx {
self self
} }
pub fn page_num_type(mut self, p: PageNumType) -> Self {
self.0 = self.0.page_num_type(p.take());
self
}
pub fn doc_grid( pub fn doc_grid(
mut self, mut self,
grid_type: docx_rs::DocGridType, grid_type: docx_rs::DocGridType,

View File

@ -12,6 +12,7 @@ mod level_override;
mod line_spacing; mod line_spacing;
mod numbering; mod numbering;
mod page_margin; mod page_margin;
mod page_num_type;
mod paragraph; mod paragraph;
mod pic; mod pic;
mod reader; mod reader;
@ -40,6 +41,7 @@ pub use level_override::*;
pub use line_spacing::*; pub use line_spacing::*;
pub use numbering::*; pub use numbering::*;
pub use page_margin::*; pub use page_margin::*;
pub use page_num_type::*;
pub use paragraph::*; pub use paragraph::*;
pub use pic::*; pub use pic::*;
pub use reader::*; pub use reader::*;

View File

@ -0,0 +1,23 @@
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Debug)]
pub struct PageNumType(docx_rs::PageNumType);
#[wasm_bindgen(js_name = createPageNumType)]
pub fn create_page_num_type(start: Option<u32>, chap_style: Option<String>) -> PageNumType {
let mut p = docx_rs::PageNumType::new();
if let Some(start) = start {
p = p.start(start);
}
if let Some(chap_style) = chap_style {
p = p.chap_style(chap_style);
}
PageNumType(p)
}
impl PageNumType {
pub fn take(self) -> docx_rs::PageNumType {
self.0
}
}

View File

@ -19614,6 +19614,7 @@ Object {
"right": 1440, "right": 1440,
"top": 1440, "top": 1440,
}, },
"pageNumType": Object {},
"pageSize": Object { "pageSize": Object {
"h": 15840, "h": 15840,
"orient": null, "orient": null,
@ -36413,6 +36414,10 @@ Object {
"right": 1701, "right": 1701,
"top": 1985, "top": 1985,
}, },
"pageNumType": Object {
"chapStyle": "1",
"start": 200,
},
"pageSize": Object { "pageSize": Object {
"h": 16838, "h": 16838,
"orient": null, "orient": null,
@ -111340,6 +111345,9 @@ Object {
"right": 1440, "right": 1440,
"top": 1440, "top": 1440,
}, },
"pageNumType": Object {
"start": 1,
},
"pageSize": Object { "pageSize": Object {
"h": 15840, "h": 15840,
"orient": null, "orient": null,
@ -116710,6 +116718,9 @@ Object {
"right": 1440, "right": 1440,
"top": 1440, "top": 1440,
}, },
"pageNumType": Object {
"start": 1,
},
"pageSize": Object { "pageSize": Object {
"h": 15840, "h": 15840,
"orient": null, "orient": null,