@@ -21,13 +21,6 @@ internal class OwDocument
2121 private MemoryStream _ms ;
2222 private PKG . MainDocumentPart _mainPart ;
2323 private readonly object _lockObject = new object ( ) ;
24- public enum ParagraphAlignment
25- {
26- Left ,
27- Center ,
28- Right ,
29- Justify
30- }
3124 private OwDocument ( )
3225 {
3326 lock ( _lockObject )
@@ -40,6 +33,7 @@ private OwDocument()
4033 _mainPart . Document = new WP . Document ( ) ;
4134 var tmp = new OT . DefaultTemplate ( ) ;
4235 tmp . CreateMainDocumentPart ( _mainPart ) ;
36+ AddNumberingDefinitions ( _pkgDocument ) ;
4337 CreateProperties ( _pkgDocument ) ;
4438 }
4539 catch ( Exception ex )
@@ -138,35 +132,44 @@ internal WP.Paragraph CreateParagraph(FF.Paragraph ffP)
138132 var paragraphStyleId = new WP . ParagraphStyleId { Val = ffP . Style } ;
139133 paragraphProperties . Append ( paragraphStyleId ) ;
140134
141- if ( Enum . TryParse < ParagraphAlignment > ( ffP . Alignment , true , out var alignmentEnum ) )
142- {
143- WP . JustificationValues justificationValue = MapAlignmentToJustification ( alignmentEnum ) ;
144- paragraphProperties . Append ( new WP . Justification { Val = justificationValue } ) ;
145- }
135+ WP . JustificationValues justificationValue = MapAlignmentToJustification ( ffP . Alignment ) ;
136+ paragraphProperties . Append ( new WP . Justification { Val = justificationValue } ) ;
137+
146138
147139 if ( ffP . Indentation != null )
148140 {
149141 SetIndentation ( paragraphProperties , ffP . Indentation ) ;
150142 }
151-
152- if ( ffP . IsNumbered )
153- {
154- var numberingProperties = new WP . NumberingProperties
155- {
156- NumberingId = new WP . NumberingId { Val = ffP . NumberingId } ,
157- NumberingLevelReference = new WP . NumberingLevelReference { Val = ffP . NumberingLevel . Value }
158- } ;
159- paragraphProperties . Append ( numberingProperties ) ;
160- }
161143
162- if ( ffP . IsBullet )
144+ if ( ffP . IsNumbered || ffP . IsBullet || ffP . IsRoman || ffP . IsAlphabeticNumber )
163145 {
164- var bulletProperties = new WP . NumberingProperties
146+ var numberingProperties = new WP . NumberingProperties ( ) ;
147+ var numberingId = new WP . NumberingId ( ) ;
148+ var numberingLevelReference = new WP . NumberingLevelReference ( ) ;
149+
150+ if ( ffP . IsBullet )
151+ {
152+ numberingId . Val = 1 ;
153+ numberingLevelReference . Val = ffP . NumberingLevel ?? 0 ;
154+ }
155+ else if ( ffP . IsNumbered )
165156 {
166- NumberingId = new WP . NumberingId { Val = 1 } ,
167- NumberingLevelReference = new WP . NumberingLevelReference { Val = 0 }
168- } ;
169- paragraphProperties . Append ( bulletProperties ) ;
157+ numberingId . Val = ffP . NumberingId <= 1 || ffP . NumberingId == null ? 2 : ffP . NumberingId ;
158+ numberingLevelReference . Val = ffP . NumberingLevel ?? 0 ;
159+ }
160+ else if ( ffP . IsAlphabeticNumber )
161+ {
162+ numberingId . Val = ffP . NumberingId <= 2 || ffP . NumberingId == null ? 3 : ffP . NumberingId ;
163+ numberingLevelReference . Val = ffP . NumberingLevel ?? 0 ;
164+ }
165+ else if ( ffP . IsRoman )
166+ {
167+ numberingId . Val = ffP . NumberingId <= 3 || ffP . NumberingId == null ? 4 : ffP . NumberingId ;
168+ numberingLevelReference . Val = ffP . NumberingLevel ?? 0 ;
169+ }
170+
171+ numberingProperties . Append ( numberingId , numberingLevelReference ) ;
172+ paragraphProperties . Append ( numberingProperties ) ;
170173 }
171174 wpParagraph . Append ( paragraphProperties ) ;
172175 }
@@ -232,6 +235,74 @@ internal WP.Paragraph CreateParagraph(FF.Paragraph ffP)
232235 }
233236 }
234237
238+ internal void AddNumberingDefinitions ( PKG . WordprocessingDocument pkgDocument )
239+ {
240+ PKG . NumberingDefinitionsPart numberingPart = pkgDocument . MainDocumentPart . NumberingDefinitionsPart ;
241+ if ( numberingPart == null )
242+ {
243+ numberingPart = pkgDocument . MainDocumentPart . AddNewPart < PKG . NumberingDefinitionsPart > ( ) ;
244+ }
245+
246+ WP . Numbering numbering = new WP . Numbering ( ) ;
247+
248+ WP . AbstractNum abstractNumBulleted = new WP . AbstractNum ( ) { AbstractNumberId = 1 } ;
249+ WP . AbstractNum abstractNumNumbered = new WP . AbstractNum ( ) { AbstractNumberId = 2 } ;
250+ WP . AbstractNum abstractNumLetter = new WP . AbstractNum ( ) { AbstractNumberId = 3 } ;
251+ WP . AbstractNum abstractNumRoman = new WP . AbstractNum ( ) { AbstractNumberId = 4 } ;
252+ string numberingStyle = "%1." ;
253+ for ( int i = 0 ; i < 9 ; i ++ )
254+ {
255+ for ( int j = 0 ; j < i ; j ++ )
256+ {
257+ numberingStyle += $ "%{ i + 1 } .";
258+ }
259+ abstractNumBulleted . Append ( CreateLevel ( i , WP . NumberFormatValues . Bullet , "•" ) ) ;
260+ abstractNumNumbered . Append ( CreateLevel ( i , WP . NumberFormatValues . Decimal , numberingStyle ) ) ;
261+ abstractNumLetter . Append ( CreateLevel ( i , WP . NumberFormatValues . LowerLetter , $ "%{ i + 1 } .") ) ;
262+ abstractNumRoman . Append ( CreateLevel ( i , WP . NumberFormatValues . LowerRoman , $ "%{ i + 1 } .") ) ;
263+ }
264+
265+ numbering . Append ( abstractNumBulleted ) ;
266+ numbering . Append ( abstractNumNumbered ) ;
267+ numbering . Append ( abstractNumLetter ) ;
268+ numbering . Append ( abstractNumRoman ) ;
269+
270+ WP . NumberingInstance numInstanceBulleted = new WP . NumberingInstance ( ) { NumberID = 1 } ;
271+ numInstanceBulleted . Append ( new WP . AbstractNumId ( ) { Val = abstractNumBulleted . AbstractNumberId } ) ;
272+
273+ WP . NumberingInstance numInstanceNumbered = new WP . NumberingInstance ( ) { NumberID = 2 } ;
274+ numInstanceNumbered . Append ( new WP . AbstractNumId ( ) { Val = abstractNumNumbered . AbstractNumberId } ) ;
275+
276+ WP . NumberingInstance numInstanceLetter = new WP . NumberingInstance ( ) { NumberID = 3 } ;
277+ numInstanceLetter . Append ( new WP . AbstractNumId ( ) { Val = abstractNumLetter . AbstractNumberId } ) ;
278+
279+ WP . NumberingInstance numInstanceRoman = new WP . NumberingInstance ( ) { NumberID = 4 } ;
280+ numInstanceRoman . Append ( new WP . AbstractNumId ( ) { Val = abstractNumRoman . AbstractNumberId } ) ;
281+
282+ numbering . Append ( numInstanceBulleted ) ;
283+ numbering . Append ( numInstanceNumbered ) ;
284+ numbering . Append ( numInstanceLetter ) ;
285+ numbering . Append ( numInstanceRoman ) ;
286+
287+ numberingPart . Numbering = numbering ;
288+ }
289+
290+ private WP . Level CreateLevel ( int levelIndex , WP . NumberFormatValues numFormatVal , string levelTextVal )
291+ {
292+ WP . Level level = new WP . Level (
293+ new WP . StartNumberingValue ( ) { Val = 1 } ,
294+ new WP . NumberingFormat ( ) { Val = numFormatVal } ,
295+ new WP . LevelText ( ) { Val = levelTextVal } ,
296+ new WP . LevelJustification ( ) { Val = WP . LevelJustificationValues . Left }
297+ )
298+ { LevelIndex = levelIndex } ;
299+ if ( numFormatVal == WP . NumberFormatValues . Bullet )
300+ {
301+ level . RemoveAllChildren < WP . StartNumberingValue > ( ) ;
302+ }
303+ return level ;
304+ }
305+
235306 private void SetIndentation ( WP . ParagraphProperties paragraphProperties , FF . Indentation ffIndentation )
236307 {
237308 var indentation = new WP . Indentation ( ) ;
@@ -259,17 +330,17 @@ private void SetIndentation(WP.ParagraphProperties paragraphProperties, FF.Inden
259330 paragraphProperties . Append ( indentation ) ;
260331 }
261332
262- private WP . JustificationValues MapAlignmentToJustification ( ParagraphAlignment alignment )
333+ private WP . JustificationValues MapAlignmentToJustification ( FF . ParagraphAlignment alignment )
263334 {
264335 switch ( alignment )
265336 {
266- case ParagraphAlignment . Left :
337+ case FF . ParagraphAlignment . Left :
267338 return WP . JustificationValues . Left ;
268- case ParagraphAlignment . Center :
339+ case FF . ParagraphAlignment . Center :
269340 return WP . JustificationValues . Center ;
270- case ParagraphAlignment . Right :
341+ case FF . ParagraphAlignment . Right :
271342 return WP . JustificationValues . Right ;
272- case ParagraphAlignment . Justify :
343+ case FF . ParagraphAlignment . Justify :
273344 return WP . JustificationValues . Both ;
274345 default :
275346 return WP . JustificationValues . Left ;
@@ -540,43 +611,82 @@ internal FF.Paragraph LoadParagraph(WP.Paragraph wpPara, int id)
540611 if ( paraStyleId != null )
541612 {
542613 if ( paraStyleId . Val != null ) ffP . Style = paraStyleId . Val . Value ;
614+ }
615+ }
616+ var numberingProperties = wpPara . ParagraphProperties ? . NumberingProperties ;
617+ if ( numberingProperties != null )
618+ {
619+ var numIdVal = numberingProperties . NumberingId ? . Val ;
620+ var levelVal = numberingProperties . NumberingLevelReference ? . Val ;
543621
544- if ( IsBulletStyle ( paraStyleId . Val . Value ) )
622+ // Check if there's a valid numbering id and level reference
623+ if ( numIdVal . HasValue && levelVal . HasValue )
624+ {
625+ // Get the numbering part from the document
626+ var numberingPart = _pkgDocument . MainDocumentPart . NumberingDefinitionsPart ;
627+ if ( numberingPart != null )
545628 {
546- ffP . IsBullet = true ;
629+ // Look for the AbstractNum that matches the numIdVal
630+ var abstractNum = numberingPart . Numbering . Elements < WP . AbstractNum > ( )
631+ . FirstOrDefault ( a => a . AbstractNumberId . Value == numIdVal . Value ) ;
632+
633+ if ( abstractNum != null )
634+ {
635+ // Get the level corresponding to the levelVal
636+ var level = abstractNum . Elements < WP . Level > ( )
637+ . FirstOrDefault ( l => l . LevelIndex . Value == levelVal . Value ) ;
638+
639+ // If the level's numbering format is bullet, set IsBullet to true
640+ if ( level != null && level . NumberingFormat != null && level . NumberingFormat . Val . Value == WP . NumberFormatValues . Bullet )
641+ {
642+ ffP . IsBullet = true ;
643+ ffP . NumberingLevel = levelVal . Value ;
644+ }
645+ else if ( level != null && level . NumberingFormat != null && level . NumberingFormat . Val . Value == WP . NumberFormatValues . LowerLetter )
646+ {
647+ ffP . IsAlphabeticNumber = true ;
648+ ffP . NumberingLevel = levelVal . Value ;
649+ }
650+ else if ( level != null && level . NumberingFormat != null && level . NumberingFormat . Val . Value == WP . NumberFormatValues . LowerRoman )
651+ {
652+ ffP . IsAlphabeticNumber = true ;
653+ ffP . NumberingLevel = levelVal . Value ;
654+ }
655+ // If the level's numbering format is not bullet, it's a numbered list
656+ else if ( level != null )
657+ {
658+ ffP . IsNumbered = true ;
659+ ffP . NumberingLevel = levelVal . Value ;
660+ ffP . NumberingId = numIdVal . Value ;
661+ }
662+ }
547663 }
548664 }
549- var numberingProperties = paraProps . Elements < WP . NumberingProperties > ( ) . FirstOrDefault ( ) ;
550- if ( numberingProperties != null )
551- {
552- ffP . IsNumbered = true ;
553- ffP . NumberingId = numberingProperties . NumberingId ? . Val ?? 0 ;
554- ffP . NumberingLevel = numberingProperties . NumberingLevelReference ? . Val ?? 0 ;
555- }
556665 }
557666 var justificationElement = paraProps . Elements < WP . Justification > ( ) . FirstOrDefault ( ) ;
558667 if ( justificationElement != null )
559668 {
560669 ffP . Alignment = MapJustificationToAlignment ( justificationElement . Val ) ;
561670 }
562671 var Indentation = paraProps . Elements < WP . Indentation > ( ) . FirstOrDefault ( ) ;
563- if ( Indentation . Left != null )
564- {
565- ffP . Indentation . Left = int . Parse ( Indentation . Left ) ;
566- }
567- if ( Indentation . Right != null )
568- {
569- ffP . Indentation . Right = int . Parse ( Indentation . Right ) ;
570- }
571- if ( Indentation . Hanging != null )
572- {
573- ffP . Indentation . Hanging = int . Parse ( Indentation . Hanging ) ;
574- }
575- if ( Indentation . FirstLine != null )
576- {
577- ffP . Indentation . FirstLine = int . Parse ( Indentation . FirstLine ) ;
672+ if ( Indentation != null ) {
673+ if ( Indentation . Left != null )
674+ {
675+ ffP . Indentation . Left = int . Parse ( Indentation . Left ) ;
676+ }
677+ if ( Indentation . Right != null )
678+ {
679+ ffP . Indentation . Right = int . Parse ( Indentation . Right ) ;
680+ }
681+ if ( Indentation . Hanging != null )
682+ {
683+ ffP . Indentation . Hanging = int . Parse ( Indentation . Hanging ) ;
684+ }
685+ if ( Indentation . FirstLine != null )
686+ {
687+ ffP . Indentation . FirstLine = int . Parse ( Indentation . FirstLine ) ;
688+ }
578689 }
579-
580690 var runs = wpPara . Elements < WP . Run > ( ) ;
581691
582692 foreach ( var wpR in runs )
@@ -613,20 +723,20 @@ private bool IsBulletStyle(string styleId)
613723 return styleId == "BulletStyle" ;
614724 }
615725
616- private string MapJustificationToAlignment ( WP . JustificationValues justificationValue )
726+ private FF . ParagraphAlignment MapJustificationToAlignment ( WP . JustificationValues justificationValue )
617727 {
618728 switch ( justificationValue )
619729 {
620730 case WP . JustificationValues . Left :
621- return " Left" ;
731+ return FF . ParagraphAlignment . Left ;
622732 case WP . JustificationValues . Center :
623- return " Center" ;
733+ return FF . ParagraphAlignment . Center ;
624734 case WP . JustificationValues . Right :
625- return " Right" ;
735+ return FF . ParagraphAlignment . Right ;
626736 case WP . JustificationValues . Both :
627- return " Justify" ;
737+ return FF . ParagraphAlignment . Justify ;
628738 default :
629- return " Left" ;
739+ return FF . ParagraphAlignment . Left ;
630740 }
631741 }
632742
0 commit comments