feat: Support w:textAlignment (#690)

main
bokuweb 2024-03-18 21:29:16 +09:00 committed by GitHub
parent 6955cd0e65
commit 13b8d9bc44
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 171 additions and 2 deletions

View File

@ -112,6 +112,7 @@ mod table_style;
mod table_width;
mod tabs;
mod text;
mod text_alignment;
mod text_border;
mod text_box;
mod text_box_content;
@ -240,6 +241,7 @@ pub use table_style::*;
pub use table_width::*;
pub use tabs::*;
pub use text::*;
pub use text_alignment::*;
pub use text_border::*;
pub use text_box::*;
pub use text_box_content::*;

View File

@ -3,8 +3,8 @@ use serde::Serialize;
use super::*;
use crate::documents::BuildXML;
use crate::types::{AlignmentType, SpecialIndentType};
use crate::xml_builder::*;
use crate::ParagraphBorderPosition;
use crate::{xml_builder::*, TextAlignmentType};
#[derive(Serialize, Debug, Clone, PartialEq, Default)]
#[serde(rename_all = "camelCase")]
@ -42,6 +42,8 @@ pub struct ParagraphProperty {
pub borders: Option<ParagraphBorders>,
#[serde(skip_serializing_if = "Option::is_none")]
pub frame_property: Option<FrameProperty>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text_alignment: Option<TextAlignment>,
}
// 17.3.1.26
@ -145,6 +147,11 @@ impl ParagraphProperty {
self
}
pub fn text_alignment(mut self, s: TextAlignmentType) -> Self {
self.text_alignment = Some(TextAlignment::new(s));
self
}
pub(crate) fn hanging_chars(mut self, chars: i32) -> Self {
if let Some(indent) = self.indent {
self.indent = Some(indent.hanging_chars(chars));
@ -192,7 +199,8 @@ fn inner_build(p: &ParagraphProperty) -> Vec<u8> {
.add_optional_child(&p.line_spacing)
.add_optional_child(&p.outline_lvl)
.add_optional_child(&p.paragraph_property_change)
.add_optional_child(&p.borders);
.add_optional_child(&p.borders)
.add_optional_child(&p.text_alignment);
if let Some(v) = p.keep_next {
if v {

View File

@ -123,6 +123,11 @@ impl Style {
self
}
pub fn text_alignment(mut self, alignment_type: TextAlignmentType) -> Self {
self.paragraph_property = self.paragraph_property.text_alignment(alignment_type);
self
}
pub fn indent(
mut self,
left: Option<i32>,

View File

@ -0,0 +1,31 @@
use serde::{Serialize, Serializer};
use crate::documents::BuildXML;
use crate::{xml_builder::*, TextAlignmentType};
#[derive(Debug, Clone, PartialEq)]
pub struct TextAlignment(pub TextAlignmentType);
impl TextAlignment {
pub fn new(val: TextAlignmentType) -> TextAlignment {
TextAlignment(val)
}
}
impl BuildXML for TextAlignment {
fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new();
let v = format!("{}", self.0);
b.text_alignment(&v).build()
}
}
impl Serialize for TextAlignment {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let v = format!("{}", self.0);
serializer.serialize_str(&v)
}
}

View File

@ -50,6 +50,12 @@ impl ElementReader for ParagraphProperty {
}
continue;
}
XMLElement::TextAlignment => {
if let Ok(v) = TextAlignmentType::from_str(&attributes[0].value) {
p = p.text_alignment(v);
}
continue;
}
XMLElement::ParagraphStyle => {
p = p.style(&attributes[0].value);
continue;

View File

@ -160,6 +160,7 @@ pub enum XMLElement {
Type,
PageNumType,
FrameProperty,
TextAlignment,
H,
HAnchor,
HSpace,
@ -405,6 +406,7 @@ impl FromStr for XMLElement {
"sdt" => Ok(XMLElement::StructuredDataTag),
"pgNumType" => Ok(XMLElement::PageNumType),
"framePr" => Ok(XMLElement::FrameProperty),
"textAlignment" => Ok(XMLElement::TextAlignment),
"h" => Ok(XMLElement::H),
"hAnchor" => Ok(XMLElement::HAnchor),
"hSpace" => Ok(XMLElement::HSpace),

View File

@ -24,6 +24,7 @@ pub mod tab_leader_type;
pub mod tab_value_type;
pub mod table_alignment_type;
pub mod table_layout_type;
pub mod text_alignment_type;
pub mod text_direction_type;
pub mod vert_align_type;
pub mod vertical_align_type;
@ -56,6 +57,7 @@ pub use tab_leader_type::*;
pub use tab_value_type::*;
pub use table_alignment_type::*;
pub use table_layout_type::*;
pub use text_alignment_type::*;
pub use text_direction_type::*;
pub use vert_align_type::*;
pub use vertical_align_type::*;

View File

@ -0,0 +1,45 @@
use std::fmt;
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
use serde::Serialize;
use super::errors;
use std::str::FromStr;
#[cfg_attr(feature = "wasm", wasm_bindgen, derive(ts_rs::TS), ts(export))]
#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum TextAlignmentType {
Auto,
Baseline,
Bottom,
Center,
Top,
}
impl fmt::Display for TextAlignmentType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TextAlignmentType::Auto => write!(f, "auto"),
TextAlignmentType::Baseline => write!(f, "baseline"),
TextAlignmentType::Bottom => write!(f, "bottom"),
TextAlignmentType::Center => write!(f, "center"),
TextAlignmentType::Top => write!(f, "top"),
}
}
}
impl FromStr for TextAlignmentType {
type Err = errors::TypeError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"auto" => Ok(TextAlignmentType::Auto),
"baseline" => Ok(TextAlignmentType::Baseline),
"bottom" => Ok(TextAlignmentType::Bottom),
"center" => Ok(TextAlignmentType::Center),
"top" => Ok(TextAlignmentType::Top),
_ => Err(errors::TypeError::FromStrError),
}
}
}

View File

@ -166,6 +166,8 @@ impl XMLBuilder {
// i.e. <w:szCs ... >
closed_with_usize!(sz_cs, "w:szCs");
closed_with_str!(text_alignment, "w:textAlignment");
closed!(field_character, "w:fldChar", "w:fldCharType", "w:dirty");
open!(open_instr_text, "w:instrText");

View File

@ -0,0 +1,2 @@
export type TextAlignmentType = "auto" | "baseline" | "bottom" | "center" | "top";

View File

@ -1,6 +1,7 @@
import { RunProperty, createDefaultRunProperty } from "./run";
import * as wasm from "./pkg";
import { TextAlignmentType } from "./json/bindings/TextAlignmentType";
export type AlignmentType =
| "center"
@ -51,6 +52,7 @@ export class LineSpacing {
export type ParagraphProperty = {
align?: AlignmentType;
textAlignment?: TextAlignmentType;
styleId?: string;
indent?: {
left: number;
@ -113,6 +115,31 @@ export const createParagraphAlignment = (
}
};
export const createParagraphTextAlignment = (
align?: TextAlignmentType | undefined
): wasm.TextAlignmentType | null => {
switch (align) {
case "auto": {
return wasm.TextAlignmentType.Auto;
}
case "baseline": {
return wasm.TextAlignmentType.Baseline;
}
case "bottom": {
return wasm.TextAlignmentType.Bottom;
}
case "center": {
return wasm.TextAlignmentType.Center;
}
case "top": {
return wasm.TextAlignmentType.Top;
}
default: {
return null;
}
}
};
export class ParagraphPropertyChange {
_author: string = "";
_date: string = "";
@ -133,6 +160,11 @@ export class ParagraphPropertyChange {
return this;
}
textAlignment(type: TextAlignmentType) {
this._property.textAlignment = type;
return this;
}
style(id: string) {
this._property.styleId = id;
return this;
@ -209,6 +241,11 @@ export const setParagraphProperty = <T extends wasm.Paragraph | wasm.Style>(
target = target.align(alignment) as T;
}
const textAlignment = createParagraphTextAlignment(property.textAlignment);
if (textAlignment != null) {
target = target.text_alignment(textAlignment) as T;
}
if (typeof property.indent !== "undefined") {
const { indent } = property;
let kind;

View File

@ -131,6 +131,11 @@ impl Paragraph {
self
}
pub fn text_alignment(mut self, alignment_type: docx_rs::TextAlignmentType) -> Paragraph {
self.0.property = self.0.property.text_alignment(alignment_type);
self
}
pub fn outline_lvl(mut self, level: usize) -> Paragraph {
self.0.property = self.0.property.outline_lvl(level);
self

View File

@ -104,6 +104,11 @@ impl Style {
self
}
pub fn text_alignment(mut self, alignment_type: docx_rs::TextAlignmentType) -> Self {
self.0.paragraph_property = self.0.paragraph_property.text_alignment(alignment_type);
self
}
pub fn indent(
mut self,
left: i32,

View File

@ -96369,6 +96369,7 @@ Object {
},
"runProperty": Object {},
"tabs": Array [],
"textAlignment": "baseline",
},
"runProperty": Object {
"fonts": Object {
@ -97842,6 +97843,7 @@ Object {
},
"runProperty": Object {},
"tabs": Array [],
"textAlignment": "bottom",
},
"runProperty": Object {
"fonts": Object {
@ -99859,6 +99861,7 @@ Object {
},
"runProperty": Object {},
"tabs": Array [],
"textAlignment": "auto",
},
"runProperty": Object {
"fonts": Object {
@ -99944,6 +99947,7 @@ Object {
},
"runProperty": Object {},
"tabs": Array [],
"textAlignment": "auto",
},
"runProperty": Object {
"fonts": Object {
@ -102528,6 +102532,7 @@ Object {
},
"runProperty": Object {},
"tabs": Array [],
"textAlignment": "baseline",
},
"runProperty": Object {
"fonts": Object {
@ -102691,6 +102696,7 @@ Object {
},
"runProperty": Object {},
"tabs": Array [],
"textAlignment": "auto",
"widowControl": true,
},
"runProperty": Object {
@ -102867,6 +102873,7 @@ Object {
"val": "left",
},
],
"textAlignment": "auto",
},
"runProperty": Object {
"fonts": Object {
@ -103226,6 +103233,7 @@ Object {
},
"runProperty": Object {},
"tabs": Array [],
"textAlignment": "auto",
},
"runProperty": Object {
"fonts": Object {
@ -103391,6 +103399,7 @@ Object {
},
"runProperty": Object {},
"tabs": Array [],
"textAlignment": "auto",
},
"runProperty": Object {
"fonts": Object {
@ -103476,6 +103485,7 @@ Object {
},
"runProperty": Object {},
"tabs": Array [],
"textAlignment": "auto",
},
"runProperty": Object {
"fonts": Object {
@ -103560,6 +103570,7 @@ Object {
},
"runProperty": Object {},
"tabs": Array [],
"textAlignment": "baseline",
"widowControl": true,
},
"runProperty": Object {
@ -103650,6 +103661,7 @@ Object {
},
"runProperty": Object {},
"tabs": Array [],
"textAlignment": "auto",
"widowControl": true,
},
"runProperty": Object {
@ -105009,6 +105021,7 @@ Object {
"val": "left",
},
],
"textAlignment": "baseline",
},
"runProperty": Object {
"fonts": Object {
@ -107763,6 +107776,7 @@ Object {
},
"runProperty": Object {},
"tabs": Array [],
"textAlignment": "baseline",
},
"runProperty": Object {
"fonts": Object {
@ -109307,6 +109321,7 @@ Object {
"val": "clear",
},
],
"textAlignment": "auto",
},
"runProperty": Object {
"bold": false,
@ -143646,6 +143661,7 @@ Object {
"val": "clear",
},
],
"textAlignment": "baseline",
},
"runProperty": Object {
"characterSpacing": 0,
@ -143762,6 +143778,7 @@ Object {
"val": "clear",
},
],
"textAlignment": "baseline",
},
"runProperty": Object {
"characterSpacing": 0,