@@ -4,6 +4,8 @@ import ModifyXmlHelper from './modify-xml-helper';
44import { XmlElement } from '../types/xml-types' ;
55import { vd } from './general-helper' ;
66import XmlElements from './xml-elements' ;
7+ import { XmlHelper } from './xml-helper' ;
8+ import { MultiTextParagraph } from '../interfaces/imulti-text' ;
79
810export default class ModifyTextHelper {
911 /**
@@ -34,8 +36,168 @@ export default class ModifyTextHelper {
3436 }
3537 } ;
3638
39+
40+ static setMultiText =
41+ ( paragraphs : MultiTextParagraph [ ] ) =>
42+ ( element : XmlElement ) : void => {
43+ // Find or create the txBody element
44+ let txBody = element . getElementsByTagName ( 'p:txBody' ) [ 0 ] ;
45+ if ( ! txBody ) {
46+ txBody = element . ownerDocument . createElement ( 'p:txBody' ) ;
47+ element . appendChild ( txBody ) ;
48+
49+ // Create required bodyPr and lstStyle elements
50+ const bodyPr = element . ownerDocument . createElement ( 'a:bodyPr' ) ;
51+ txBody . appendChild ( bodyPr ) ;
52+
53+ const lstStyle = element . ownerDocument . createElement ( 'a:lstStyle' ) ;
54+ txBody . appendChild ( lstStyle ) ;
55+ }
56+
57+ // Clear existing paragraphs
58+ const existingParagraphs = txBody . getElementsByTagName ( 'a:p' ) ;
59+ const length = existingParagraphs . length ;
60+ for ( let i = length - 1 ; i >= 0 ; i -- ) {
61+ const paragraph = existingParagraphs [ i ] ;
62+ paragraph . parentNode . removeChild ( paragraph ) ;
63+ }
64+
65+ // Process each paragraph
66+ paragraphs . forEach ( para => {
67+ // Create a new paragraph element
68+ const p = element . ownerDocument . createElement ( 'a:p' ) ;
69+ txBody . appendChild ( p ) ;
70+
71+ // Create paragraph properties
72+ const pPr = element . ownerDocument . createElement ( 'a:pPr' ) ;
73+ p . appendChild ( pPr ) ;
74+
75+ // Apply paragraph styling
76+ if ( para . paragraph ) {
77+ // Set bullet level
78+ if ( para . paragraph . level !== undefined ) {
79+ pPr . setAttribute ( 'lvl' , String ( para . paragraph . level ) ) ;
80+ }
81+
82+ // Set bullet configuration
83+ if ( para . paragraph . bullet ) {
84+ const buChar = element . ownerDocument . createElement ( 'a:buChar' ) ;
85+ buChar . setAttribute ( 'char' , '•' ) ; // Default bullet character
86+ pPr . appendChild ( buChar ) ;
87+ } else if ( para . paragraph . level === 0 || para . paragraph . bullet === false ) {
88+ const buNone = element . ownerDocument . createElement ( 'a:buNone' ) ;
89+ pPr . appendChild ( buNone ) ;
90+ }
91+
92+ // Set alignment
93+ if ( para . paragraph . alignment ) {
94+ const algn = element . ownerDocument . createElement ( 'a:algn' ) ;
95+ algn . setAttribute ( 'val' , para . paragraph . alignment ) ;
96+ pPr . appendChild ( algn ) ;
97+ }
98+
99+ // Set custom indentation
100+ if ( para . paragraph . indent !== undefined ) {
101+ pPr . setAttribute ( 'indent' , String ( para . paragraph . indent ) ) ;
102+ }
103+
104+ // Set left margin
105+ if ( para . paragraph . marginLeft !== undefined ) {
106+ pPr . setAttribute ( 'marL' , String ( para . paragraph . marginLeft ) ) ;
107+ }
108+
109+ // Set line spacing
110+ if ( para . paragraph . lineSpacing !== undefined ) {
111+ const lnSpc = element . ownerDocument . createElement ( 'a:lnSpc' ) ;
112+ const spcPts = element . ownerDocument . createElement ( 'a:spcPts' ) ;
113+ spcPts . setAttribute ( 'val' , String ( Math . round ( para . paragraph . lineSpacing * 100 ) ) ) ; // Convert to 100ths of a point
114+ lnSpc . appendChild ( spcPts ) ;
115+ pPr . appendChild ( lnSpc ) ;
116+ }
117+
118+ // Set space before paragraph
119+ if ( para . paragraph . spaceBefore !== undefined ) {
120+ const spcBef = element . ownerDocument . createElement ( 'a:spcBef' ) ;
121+ const spcPts = element . ownerDocument . createElement ( 'a:spcPts' ) ;
122+ spcPts . setAttribute ( 'val' , String ( Math . round ( para . paragraph . spaceBefore * 100 ) ) ) ; // Convert to 100ths of a point
123+ spcBef . appendChild ( spcPts ) ;
124+ pPr . appendChild ( spcBef ) ;
125+ }
126+
127+ // Set space after paragraph
128+ if ( para . paragraph . spaceAfter !== undefined ) {
129+ const spcAft = element . ownerDocument . createElement ( 'a:spcAft' ) ;
130+ const spcPts = element . ownerDocument . createElement ( 'a:spcPts' ) ;
131+ spcPts . setAttribute ( 'val' , String ( Math . round ( para . paragraph . spaceAfter * 100 ) ) ) ; // Convert to 100ths of a point
132+ spcAft . appendChild ( spcPts ) ;
133+ pPr . appendChild ( spcAft ) ;
134+ }
135+ }
136+
137+ // Handle text runs - if textRuns array exists, use it; otherwise, create a single run with paragraph text
138+ if ( para . textRuns && para . textRuns . length > 0 ) {
139+ // Process each text run in the paragraph
140+ para . textRuns . forEach ( run => {
141+ // Create text run
142+ const r = element . ownerDocument . createElement ( 'a:r' ) ;
143+ p . appendChild ( r ) ;
144+
145+ // Create text properties element
146+ const rPr = element . ownerDocument . createElement ( 'a:rPr' ) ;
147+ r . appendChild ( rPr ) ;
148+
149+ // Apply text styling if specified
150+ if ( run . style ) {
151+ ModifyTextHelper . style ( run . style ) ( rPr ) ;
152+ }
153+
154+ // Create text element
155+ const t = element . ownerDocument . createElement ( 'a:t' ) ;
156+ r . appendChild ( t ) ;
157+
158+ // Handle empty strings with xml:space="preserve"
159+ if ( run . text === '' ) {
160+ t . setAttribute ( 'xml:space' , 'preserve' ) ;
161+ }
162+
163+ // Set text content
164+ const textNode = element . ownerDocument . createTextNode ( run . text || '' ) ;
165+ t . appendChild ( textNode ) ;
166+ } ) ;
167+ } else if ( para . text !== undefined ) {
168+ // Create a single text run for the paragraph text
169+ const r = element . ownerDocument . createElement ( 'a:r' ) ;
170+ p . appendChild ( r ) ;
171+
172+ // Create text properties element
173+ const rPr = element . ownerDocument . createElement ( 'a:rPr' ) ;
174+ r . appendChild ( rPr ) ;
175+
176+ // Apply text styling
177+ if ( para . style ) {
178+ ModifyTextHelper . style ( para . style ) ( rPr ) ;
179+ }
180+
181+ // Create text element
182+ const t = element . ownerDocument . createElement ( 'a:t' ) ;
183+ r . appendChild ( t ) ;
184+
185+ // Handle empty strings with xml:space="preserve"
186+ if ( para . text === '' ) {
187+ t . setAttribute ( 'xml:space' , 'preserve' ) ;
188+ }
189+
190+ // Set text content
191+ const textNode = element . ownerDocument . createTextNode ( String ( para . text || '' ) ) ;
192+ t . appendChild ( textNode ) ;
193+ }
194+ } ) ;
195+ } ;
196+
197+
37198 static setBulletList =
38- ( list ) => ( element : XmlElement ) : void => {
199+ ( list ) =>
200+ ( element : XmlElement ) : void => {
39201 const xmlElements = new XmlElements ( element ) ;
40202 xmlElements . addBulletList ( list ) ;
41203 } ;
@@ -105,4 +267,26 @@ export default class ModifyTextHelper {
105267 ( element : XmlElement ) : void => {
106268 ModifyXmlHelper . booleanAttribute ( 'i' , isItalics ) ( element ) ;
107269 } ;
270+
271+ static htmlToText = ( html : string ) => {
272+ html =
273+ '<p><span style="font-size: 24px;">Testing layouts and exporting them.</span></p>\n' +
274+ '<ul>\n' +
275+ '<li>level 1 - 1</li>\n' +
276+ '<li>level 1 - 2</li>\n' +
277+ '<ul>\n' +
278+ '<li>level 1-2-1 <em>italics</em></li>\n' +
279+ '</ul>\n' +
280+ '<li>level 1 - 3</li>\n' +
281+ '<ul>\n' +
282+ '<li>level 1 - 3 - 1</li>\n' +
283+ '</ul>\n' +
284+ '</ul>\n' +
285+ '<p>Testing testing testing</p>\n' +
286+ '<p><strong>bold text</strong></p>\n' ;
287+
288+ return ( element : XmlElement ) : void => {
289+ XmlHelper . dump ( element ) ;
290+ } ;
291+ } ;
108292}
0 commit comments