Skip to content

Commit

Permalink
feat: update
Browse files Browse the repository at this point in the history
  • Loading branch information
qq15725 committed Dec 6, 2024
1 parent 4977255 commit 5168c2a
Show file tree
Hide file tree
Showing 32 changed files with 625 additions and 225 deletions.
91 changes: 44 additions & 47 deletions src/core/OXML.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,15 @@ export interface OXMLChildDefinition {
export interface OXMLDefinition {
tag?: string
namespace?: string
attributes?: Record<string, OXMLAttributeDefinition>
properties?: Record<string, OXMLPropertyDefinition>
children?: OXMLChildDefinition[]
attributes: Record<string, OXMLAttributeDefinition>
properties: Record<string, OXMLPropertyDefinition>
children: OXMLChildDefinition[]
}

export function defineElement(tag: string) {
return (constructor: any) => {
const proto = constructor.prototype
let definition = OXML.protoToDefinition.get(proto)
if (!definition) {
definition = {} as OXMLDefinition
OXML.protoToDefinition.set(proto, definition)
}
const definition = OXML.makeDefinition(proto)
const tagArr = tag.split(':')
definition.tag = tag
definition.namespace = tagArr.length > 1 ? tagArr[0] : undefined
Expand All @@ -55,12 +51,7 @@ export function defineAttribute(
defaultValue?: any,
) {
return function (proto: any, name: any) {
let definition = OXML.protoToDefinition.get(proto)
if (!definition) {
definition = {} as OXMLDefinition
OXML.protoToDefinition.set(proto, definition)
}
definition.attributes ??= {}
const definition = OXML.makeDefinition(proto)
definition.attributes[attrName] = { name, alias: attrName, type, defaultValue }
Object.defineProperty(proto, name, {
get() {
Expand All @@ -72,31 +63,26 @@ export function defineAttribute(
}
}

export function defineProperty(propName: string) {
export function defineProperty(aliasName?: string) {
return function (proto: any, name: any) {
let definition = OXML.protoToDefinition.get(proto)
if (!definition) {
definition = {} as OXMLDefinition
OXML.protoToDefinition.set(proto, definition)
const alias = aliasName ?? name
const definition = OXML.makeDefinition(proto)
definition.properties[alias] = { name, alias }
if (name !== alias) {
Object.defineProperty(proto, name, {
get() {
return (this as OXML).offsetGet(alias)
},
configurable: true,
enumerable: true,
})
}
definition.properties ??= {}
definition.properties[propName] = { name, alias: propName }
Object.defineProperty(proto, name, {
get() {
return (this as OXML).offsetGet(propName)
},
})
}
}

export function defineChild(tag: string, defaultValue?: any, isArray = false) {
return function (proto: any, name: any) {
let definition = OXML.protoToDefinition.get(proto)
if (!definition) {
definition = {} as OXMLDefinition
OXML.protoToDefinition.set(proto, definition)
}
definition.children ??= []
const definition = OXML.makeDefinition(proto)
definition.children.push({ tag, defaultValue, isArray })
Object.defineProperty(proto, name, {
get() {
Expand Down Expand Up @@ -126,13 +112,28 @@ export class OXML {
return this.tagToConstructor.get(tag)
}

static makeDefinition(proto: any): OXMLDefinition {
let definition = OXML.protoToDefinition.get(proto)
if (!definition) {
definition = {
attributes: {},
properties: {
tag: { name: 'tag', alias: 'tag' },
},
children: [],
} as unknown as OXMLDefinition
OXML.protoToDefinition.set(proto, definition)
}
return definition
}

static getDefinition(proto: any): OXMLDefinition | undefined {
let definition: OXMLDefinition | undefined
let cur = proto
while (cur) {
const _definition = this.protoToDefinition.get(cur)
if (_definition) {
definition = deepMerge(definition ?? {}, _definition)
definition = deepMerge(definition ?? {}, _definition) as any
}
cur = Object.getPrototypeOf(cur)
}
Expand Down Expand Up @@ -196,19 +197,28 @@ export class OXML {
case 'boolean':
return !!value
case 'degree':
case 'ST_Angle':
return Number(value) / 60000
case 'fontSize':
return Number(value) / 100
case 'number':
case 'SByteValue':
return Number(value)
case 'string':
case 'HexBinaryValue':
case 'StringValue':
return String(value)
case 'emu':
case 'ST_Coordinate32':
case 'ST_AdjCoordinate':
return (Number(value) / 914400) * OXML.DPI
case 'dxa':
return (Number(value) / 1440) * OXML.DPI
case 'percentage':
case 'ST_TextSpacingPercentOrPercentString':
return Number(value) / 1000
case 'ST_TextSpacingPoint':
return Number(value) / 100
case 'rate':
return Number(value) / 100000
case 'lineHeight':
Expand Down Expand Up @@ -335,19 +345,6 @@ export class OXML {
}
})
}
definition?.children?.forEach((child) => {
child.tag
})
return {
...properties,
}
// return {
// ...this.getAttributes(),
// ...Object.fromEntries(this.getChildren().map((child) => {
// const tag = child.tag ?? child.element.tagName
// const tagArr = tag.split(':')
// return [tagArr[tagArr.length - 1], child.toJSON()]
// })),
// }
return properties
}
}
8 changes: 4 additions & 4 deletions src/openxml/drawing/BlipFill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export class BlipFill extends OXML {
@defineAttribute('rotWithShape', 'boolean') declare rotWithShape?: boolean
@defineAttribute('dpi', 'number') declare dpi?: number

@defineChild('a:blip') declare blip: Blip
@defineChild('a:srcRect') declare srcRect: SourceRectangle
@defineChild('a:stretch') declare stretch: Stretch
@defineChild('a:tile') declare tile: Tile
@defineChild('a:blip') declare blip?: Blip
@defineChild('a:srcRect') declare srcRect?: SourceRectangle
@defineChild('a:stretch') declare stretch?: Stretch
@defineChild('a:tile') declare tile?: Tile
}
32 changes: 23 additions & 9 deletions src/openxml/drawing/BodyProperties.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
import type { TextWrappingValues } from './TextWrappingValues'
import type {
TextAnchoringTypeValues,
TextHorizontalOverflowValues,
TextVerticalOverflowValues,
TextVerticalValues,
TextWrappingValues,
} from './_types'
import { defineAttribute, defineElement, OXML } from '../../core'
import { TextAnchoringTypeValues } from './TextAnchoringTypeValues'

/**
* @link https://learn.microsoft.com/dotnet/api/documentformat.openxml.drawing.bodyproperties
*/
@defineElement('a:bodyPr')
export class BodyProperties extends OXML {
@defineAttribute('anchor', TextAnchoringTypeValues) declare anchor?: TextAnchoringTypeValues
@defineAttribute('anchor') declare anchor?: TextAnchoringTypeValues
@defineAttribute('anchorCtr', 'boolean') declare anchorCtr?: boolean
@defineAttribute('bIns', 'ST_Coordinate32') declare bIns?: number
@defineAttribute('numCol', 'ST_TextColumnCount') declare numCol?: number
@defineAttribute('spcCol', 'ST_PositiveCoordinate32') declare spcCol?: number
@defineAttribute('compatLnSpc', 'boolean') declare compatLnSpc?: boolean
@defineAttribute('forceAA', 'boolean') declare forceAA?: boolean
@defineAttribute('fromWordArt', 'boolean') declare fromWordArt?: boolean
@defineAttribute('horzOverflow') declare horzOverflow?: TextHorizontalOverflowValues
@defineAttribute('lIns', 'ST_Coordinate32') declare lIns?: number
@defineAttribute('rIns', 'ST_Coordinate32') declare rIns?: number
@defineAttribute('rtlCol', 'boolean') declare rtlCol?: boolean
@defineAttribute('rot', 'ST_Angle') declare rot?: number
@defineAttribute('tIns', 'ST_Coordinate32') declare tIns?: number
@defineAttribute('upright', 'boolean') declare upright?: boolean
@defineAttribute('spcFirstLastPara', 'boolean') declare spcFirstLastPara?: boolean
@defineAttribute('lIns', 'emu') declare lIns?: number
@defineAttribute('tIns', 'emu') declare tIns?: number
@defineAttribute('rIns', 'emu') declare rIns?: number
@defineAttribute('bIns', 'emu') declare bIns?: number
@defineAttribute('rot', 'degree') declare rot?: number
@defineAttribute('vert') declare vert?: TextVerticalValues
@defineAttribute('vertOverflow') declare vertOverflow?: TextVerticalOverflowValues
@defineAttribute('wrap') declare wrap?: TextWrappingValues
@defineAttribute('upright', 'boolean') declare upright?: boolean
}
9 changes: 9 additions & 0 deletions src/openxml/drawing/Break.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineElement, OXML } from '../../core'

/**
* @link https://learn.microsoft.com/dotnet/api/documentformat.openxml.drawing.break
*/
@defineElement('a:br')
export class Break extends OXML {
//
}
10 changes: 10 additions & 0 deletions src/openxml/drawing/ComplexScriptFont.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineElement } from '../../core'
import { _Font } from './_Font'

/**
* https://learn.microsoft.com/dotnet/api/documentformat.openxml.drawing.complexscriptfont
*/
@defineElement('a:cs')
export class ComplexScriptFont extends _Font {
//
}
10 changes: 10 additions & 0 deletions src/openxml/drawing/EastAsianFont.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineElement } from '../../core'
import { _Font } from './_Font'

/**
* https://learn.microsoft.com/dotnet/api/documentformat.openxml.drawing.eastasianfont
*/
@defineElement('a:ea')
export class EastAsianFont extends _Font {
//
}
9 changes: 9 additions & 0 deletions src/openxml/drawing/EndParagraphRunProperties.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineElement, OXML } from '../../core'

/**
* @link https://learn.microsoft.com/dotnet/api/documentformat.openxml.drawing.endparagraphrunproperties
*/
@defineElement('a:endParaRPr')
export class EndParagraphRunProperties extends OXML {
// TODO
}
10 changes: 10 additions & 0 deletions src/openxml/drawing/Field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineAttribute, defineElement, OXML } from '../../core'

/**
* @link https://learn.microsoft.com/dotnet/api/documentformat.openxml.drawing.field
*/
@defineElement('a:fld')
export class Field extends OXML {
@defineAttribute('id') declare id?: string
@defineAttribute('type') declare type?: string
}
10 changes: 10 additions & 0 deletions src/openxml/drawing/LatinFont.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineElement } from '../../core'
import { _Font } from './_Font'

/**
* https://learn.microsoft.com/dotnet/api/documentformat.openxml.drawing.latinfont
*/
@defineElement('a:latin')
export class LatinFont extends _Font {
//
}
12 changes: 12 additions & 0 deletions src/openxml/drawing/LineSpacing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { SpacingPercent } from './SpacingPercent'
import type { SpacingPoints } from './SpacingPoints'
import { defineChild, defineElement, OXML } from '../../core'

/**
* https://learn.microsoft.com/dotnet/api/documentformat.openxml.drawing.linespacing
*/
@defineElement('a:lnSpc')
export class LineSpacing extends OXML {
@defineChild('a:spcPct') declare spcPct?: SpacingPercent
@defineChild('a:spcPts') declare spcPts?: SpacingPoints
}
49 changes: 39 additions & 10 deletions src/openxml/drawing/Paragraph.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,51 @@
import type { TextAlignmentTypeValues } from './TextAlignmentTypeValues'
import type { Break } from './Break'
import type { EndParagraphRunProperties } from './EndParagraphRunProperties'
import type { Field } from './Field'
import type { ParagraphProperties } from './ParagraphProperties'
import type { Run } from './Run'
import { defineChild, defineElement, defineProperty, OXML } from '../../core'
import { ParagraphProperties } from './ParagraphProperties'
import { Run } from './Run'

/**
* https://learn.microsoft.com/dotnet/api/documentformat.openxml.drawing.paragraph
*/
@defineElement('a:p')
export class Paragraph extends OXML {
@defineChild('p:pPr', ParagraphProperties) declare pPr: ParagraphProperties
@defineChild('p:r', Run) declare rList: Run[]
@defineChild('a:fld') declare fld?: Field
@defineChild('a:pPr') declare pPr: ParagraphProperties

@defineProperty('pPr.marL', 0) declare marginLeft: number
@defineProperty('pPr.marR', 0) declare marginRight: number
@defineProperty('pPr.indent', 0) declare textIndent: number
@defineProperty() style = new _ParagraphStyle(this)
@defineProperty('pPr.lvl') declare level?: number
@defineProperty('pPr.fontAlgn') declare fontAlign?: string
@defineProperty('_children') declare children?: (Break | Run | EndParagraphRunProperties)[]

get textAlign(): TextAlignmentTypeValues | undefined { return this.pPr.algn }
get rightToLeft(): string | undefined { return this.pPr.rtl }
get _children(): (Break | Run | EndParagraphRunProperties)[] {
return Array.from(this.element.children).map((element) => {
switch (element.tagName) {
case 'a:fld':
case 'a:pPr':
return undefined
case 'a:br':
case 'a:r':
case 'a:endParaRPr':
default:
return OXML.make(element)
}
}).filter(Boolean) as any
}
}

export class _ParagraphStyle extends OXML {
@defineProperty('_parent.pPr.marL') declare marginLeft?: number
@defineProperty('_parent.pPr.marR') declare marginRight?: number
@defineProperty('_parent.pPr.indent') declare textIndent: number
@defineProperty('_parent.pPr.lnSpc.spcPct.val') declare lineHeight?: number

get textAlign() { return this._parent.pPr.algn }
get rightToLeft(): string | undefined { return this._parent.pPr.rtl }

constructor(
protected _parent: Paragraph,
) {
super()
}
}
Loading

0 comments on commit 5168c2a

Please sign in to comment.