ooxml

Check-in [f32dea867e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:set namespaces while serialise; affected: createNodeCmd, createDocumentNS and setAttributeNS
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | namespaces
Files: files | file ages | folders
SHA3-256: f32dea867e52be44d54a29c22f8162e38d63cfaec0546f60fe3dfdcb79072628
User & Date: alex 2019-11-16 10:33:00
Context
2019-11-16
10:37
merged from namespaces check-in: 6931dd69d4 user: alex tags: trunk
10:33
set namespaces while serialise; affected: createNodeCmd, createDocumentNS and setAttributeNS Closed-Leaf check-in: f32dea867e user: alex tags: namespaces
2019-11-15
07:42
cosmetic cleanup selectNodes check-in: 08dcd5f665 user: alex tags: namespaces
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ooxml.tcl.

1424
1425
1426
1427
1428
1429
1430





























1431
1432
1433
1434
1435
1436
1437
1438
....
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
....
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
....
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
....
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
....
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
....
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
....
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
....
3206
3207
3208
3209
3210
3211
3212
3213
3214

3215
3216
3217
3218
3219


3220
3221
3222
3223
3224
3225
3226
....
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
    workbookPr workbookView
    xf
  }

  namespace eval ::ooxml "dom createNodeCmd textNode Text; namespace export Text"

  foreach tag $elementNodes {





























    namespace eval ::ooxml "dom createNodeCmd -tagName $tag elementNode Tag_$tag; namespace export Tag_$tag"
  }
  
  set initNodeCmds 1
}


#
................................................................................
	dict set cells($n) v $pos
      }
    }
    unset -nocomplain n v
    array unset lookup
    
    # _rels/.rels
    set doc [dom createDocument Relationships]
    set root [$doc documentElement]

    set rId 0

    $root setAttribute xmlns $xmlns(PR)

    $root appendFromScript {
      Tag_Relationship Id rId1 Type http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument Target xl/workbook.xml {}
      Tag_Relationship Id rId2 Type http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties Target docProps/app.xml {}
      Tag_Relationship Id rId3 Type http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties Target docProps/core.xml {}
    }
    ::ooxml::Dom2zip $zf $root "_rels/.rels" cd count
    $doc delete

    # [Content_Types].xml
    set doc [dom createDocument Types]
    set root [$doc documentElement]


    $root setAttribute xmlns $xmlns(CT)

    $root appendFromScript {
      Tag_Default Extension xml ContentType application/xml {}
      Tag_Default Extension rels ContentType application/vnd.openxmlformats-package.relationships+xml {}
      Tag_Override PartName /xl/workbook.xml ContentType application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml {}
      Tag_Override PartName /xl/worksheets/sheet1.xml ContentType application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml {}
      for {set ws 1} {$ws <= $obj(sheets)} {incr ws} {
	Tag_Override PartName /xl/theme/theme${ws}.xml ContentType application/vnd.openxmlformats-officedocument.theme+xml {}
................................................................................
      Tag_Override PartName /docProps/core.xml ContentType application/vnd.openxmlformats-package.core-properties+xml {}
      Tag_Override PartName /docProps/app.xml ContentType application/vnd.openxmlformats-officedocument.extended-properties+xml {}
    }
    ::ooxml::Dom2zip $zf $root "\[Content_Types\].xml" cd count
    $doc delete

    # docProps/app.xml
    set doc [set obj(doc,) [dom createDocument Properties]]
    set root [$doc documentElement]

    $root setAttribute xmlns $xmlns(EP)
    $root setAttribute xmlns:vt $xmlns(vt)

    $root appendFromScript {
      Tag_Application { Text $obj(application) }
      Tag_DocSecurity { Text 0 }
      Tag_ScaleCrop { Text false }
      Tag_HeadingPairs {
	Tag_vt:vector size 2 baseType variant {
................................................................................
      Tag_HyperlinksChanged { Text false }
      Tag_AppVersion { Text 1.0 }
    }
    ::ooxml::Dom2zip $zf $root "docProps/app.xml" cd count
    $doc delete

    # docProps/core.xml
    set doc [dom createDocument cp:coreProperties]
    set root [$doc documentElement]

    $root setAttribute xmlns:cp $xmlns(cp)
    $root setAttribute xmlns:dc $xmlns(dc)
    $root setAttribute xmlns:dcterms $xmlns(dcterms)
    $root setAttribute xmlns:dcmitype $xmlns(dcmitype)
    $root setAttribute xmlns:xsi $xmlns(xsi)

    $root appendFromScript {
      Tag_dc:creator { Text $obj(creator) }
      Tag_cp:lastModifiedBy { Text $obj(lastModifiedBy) }
      Tag_dcterms:created xsi:type dcterms:W3CDTF { Text $obj(created) }
      Tag_dcterms:modified xsi:type dcterms:W3CDTF { Text $obj(modified) }
    }
    ::ooxml::Dom2zip $zf $root "docProps/core.xml" cd count
    $doc delete

    # xl/_rels/workbook.xml.rels
    set doc [dom createDocument Relationships]
    set root [$doc documentElement]

    $root setAttribute xmlns $xmlns(PR)

    $root appendFromScript {
      for {set ws 1} {$ws <= $obj(sheets)} {incr ws} {
	Tag_Relationship Id rId$ws Type http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet Target worksheets/sheet${ws}.xml {}
      }
      set rId [incr ws -1]
      Tag_Relationship Id rId[incr rId] Type http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme Target theme/theme1.xml {}
      Tag_Relationship Id rId[incr rId] Type http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles Target styles.xml {}
................................................................................
    }
    ::ooxml::Dom2zip $zf $root "xl/_rels/workbook.xml.rels" cd count
    $doc delete


    # xl/sharedStrings.xml
    if {$obj(sharedStrings) > 0} {
      set doc [dom createDocument sst]
      set root [$doc documentElement]

      $root setAttribute xmlns $xmlns(M)
      $root setAttribute count [llength $sharedStrings]
      $root setAttribute uniqueCount [llength $sharedStrings]

      $root appendFromScript {
	foreach string $sharedStrings {
	  Tag_si {
	    Tag_t { Text $string }
................................................................................
      ::ooxml::Dom2zip $zf $root "xl/sharedStrings.xml" cd count
      $doc delete
    }


    # xl/calcChain.xml
    if {$obj(calcChain)} {
      set doc [dom createDocument calcChain]
      set root [$doc documentElement]

      $root setAttribute xmlns $xmlns(M)

      $root appendFromScript {
	Tag_c r C1 i 3 l 1 {}
	Tag_c r A3 i 2 {}
      }
      ::ooxml::Dom2zip $zf $root "xl/calcChain.xml" cd count
      $doc delete
    }


    # xl/styles.xml
    set doc [dom createDocument styleSheet]
    set root [$doc documentElement]

    $root setAttribute xmlns $xmlns(M)
    $root setAttribute xmlns:mc $xmlns(mc)
    $root setAttribute xmlns:x14ac $xmlns(x14ac)
    $root setAttribute mc:Ignorable x14ac

    $root appendFromScript {
      if {$obj(numFmts) > $::ooxml::defaults(numFmts,start)} {
	Tag_numFmts count [llength [array names numFmts]] {
	  foreach idx [lsort -integer [array names numFmts]] {
	    Tag_numFmt numFmtId $idx formatCode $numFmts($idx) {}
................................................................................
      Tag_tableStyles count 0 {}
    }
    ::ooxml::Dom2zip $zf $root "xl/styles.xml" cd count
    $doc delete


    # xl/theme/theme1.xml
    set doc [dom createDocument a:theme]
    set root [$doc documentElement]

    $root setAttribute xmlns:a $xmlns(a)
    $root setAttribute name Office-Design

    $root appendFromScript {
      Tag_a:themeElements {
	Tag_a:clrScheme name Office {
	  Tag_a:dk1 {
	    Tag_a:sysClr val windowText lastClr 000000 {}
................................................................................
      Tag_a:extraClrSchemeLst {}
    }
    ::ooxml::Dom2zip $zf $root "xl/theme/theme1.xml" cd count
    $doc delete


    # xl/workbook.xml
    set doc [dom createDocument workbook]
    set root [$doc documentElement]

    $root setAttribute xmlns $xmlns(M)
    $root setAttribute xmlns:r $xmlns(r)

    $root appendFromScript {
      Tag_fileVersion appName xl lastEdited 5 lowestEdited 5 rupBuild 5000 {}
      Tag_workbookPr showInkAnnotation 0 autoCompressPictures 0 {}
      Tag_bookViews {
	Tag_workbookView activeTab 1 {}
      }
................................................................................
    ::ooxml::Dom2zip $zf $root "xl/workbook.xml" cd count
    $doc delete


    # xl/worksheets/sheet1.xml SHEET

    for {set ws 1} {$ws <= $obj(sheets)} {incr ws} {
      set doc [dom createDocument worksheet]
      set root [$doc documentElement]

      $root setAttribute xmlns $xmlns(M)
      $root setAttribute xmlns:r $xmlns(r)
      $root setAttribute xmlns:mc $xmlns(mc)
      $root setAttribute xmlns:x14ac $xmlns(x14ac)
      $root setAttribute mc:Ignorable x14ac



      $root appendFromScript {
	Tag_dimension ref [::ooxml::RowColumnToString $obj(dminrow,$ws),$obj(dmincol,$ws)]:[::ooxml::RowColumnToString $obj(dmaxrow,$ws),$obj(dmaxcol,$ws)] {}
	Tag_sheetViews {
	  Tag_sheetView workbookViewId 0 {
	    if {$obj(freeze,$ws) ne {}} {
	      lassign [split [::ooxml::StringToRowColumn $obj(freeze,$ws)] ,] row col
................................................................................
	      Tag_mergeCell ref $item {}
	    }
	  }
	}
	Tag_pageMargins left 0.75 right 0.75 top 1 bottom 1 header 0.5 footer 0.5 {}
      }

      if {[set colsNode [$root selectNodes /worksheet/cols]] ne {}} {
	if {[info exists obj($ws,cols)] && $obj($ws,cols) > 0} {
	  $colsNode appendFromScript {
	    foreach idx [lsort -dictionary [array names cols $ws,*]] {
	      set attr {}
	      lappend attr min [expr {[dict get $cols($idx) min] + 1}] max [expr {[dict get $cols($idx) max] + 1}]
	      if {[dict get $cols($idx) width] ne {}} {
		lappend attr width [dict get $cols($idx) width]







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







 







|




<
<









|


<
<
<







 







|


|
<







 







|


|
<
|
|
|











|


<
<







 







|


<







 







|


<
<










|


|
<
|







 







|


<







 







|


|
<







 







|

>
|
|
<
|

>
>







 







|







1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
....
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579


2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591



2592
2593
2594
2595
2596
2597
2598
....
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617

2618
2619
2620
2621
2622
2623
2624
....
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655

2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672


2673
2674
2675
2676
2677
2678
2679
....
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695

2696
2697
2698
2699
2700
2701
2702
....
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717


2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731

2732
2733
2734
2735
2736
2737
2738
2739
....
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867

2868
2869
2870
2871
2872
2873
2874
....
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199

3200
3201
3202
3203
3204
3205
3206
....
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231

3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
....
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
    workbookPr workbookView
    xf
  }

  namespace eval ::ooxml "dom createNodeCmd textNode Text; namespace export Text"

  foreach tag $elementNodes {
    switch -glob -- $tag {
      a:* {
	set ns $xmlns(a)
      }
      cp:* {
	set ns $xmlns(cp)
      }
      dc:* {
	set ns $xmlns(dc)
      }
      dcterms:* {
	set ns $xmlns(dcterms)
      }
      vt:* {
	set ns $xmlns(vt)
      }
      AppVersion - Application - Company - DocSecurity - HeadingPairs - HyperlinksChanged - LinksUpToDate - ScaleCrop - SharedDoc - TitlesOfParts {
	set ns $xmlns(EP)
      }
      Default - Override {
	set ns $xmlns(CT)
      }
      Relationship {
	set ns $xmlns(PR)
      }
      default {
	set ns $xmlns(M)
      }
    }
    namespace eval ::ooxml "dom createNodeCmd -tagName $tag -namespace $ns elementNode Tag_$tag; namespace export Tag_$tag"
  }
  
  set initNodeCmds 1
}


#
................................................................................
	dict set cells($n) v $pos
      }
    }
    unset -nocomplain n v
    array unset lookup
    
    # _rels/.rels
    set doc [dom createDocumentNS $xmlns(PR) Relationships]
    set root [$doc documentElement]

    set rId 0



    $root appendFromScript {
      Tag_Relationship Id rId1 Type http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument Target xl/workbook.xml {}
      Tag_Relationship Id rId2 Type http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties Target docProps/app.xml {}
      Tag_Relationship Id rId3 Type http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties Target docProps/core.xml {}
    }
    ::ooxml::Dom2zip $zf $root "_rels/.rels" cd count
    $doc delete

    # [Content_Types].xml
    set doc [dom createDocumentNS $xmlns(CT) Types]
    set root [$doc documentElement]




    $root appendFromScript {
      Tag_Default Extension xml ContentType application/xml {}
      Tag_Default Extension rels ContentType application/vnd.openxmlformats-package.relationships+xml {}
      Tag_Override PartName /xl/workbook.xml ContentType application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml {}
      Tag_Override PartName /xl/worksheets/sheet1.xml ContentType application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml {}
      for {set ws 1} {$ws <= $obj(sheets)} {incr ws} {
	Tag_Override PartName /xl/theme/theme${ws}.xml ContentType application/vnd.openxmlformats-officedocument.theme+xml {}
................................................................................
      Tag_Override PartName /docProps/core.xml ContentType application/vnd.openxmlformats-package.core-properties+xml {}
      Tag_Override PartName /docProps/app.xml ContentType application/vnd.openxmlformats-officedocument.extended-properties+xml {}
    }
    ::ooxml::Dom2zip $zf $root "\[Content_Types\].xml" cd count
    $doc delete

    # docProps/app.xml
    set doc [set obj(doc,) [dom createDocumentNS $xmlns(EP) Properties]]
    set root [$doc documentElement]

    $root setAttributeNS {} xmlns:vt $xmlns(vt)


    $root appendFromScript {
      Tag_Application { Text $obj(application) }
      Tag_DocSecurity { Text 0 }
      Tag_ScaleCrop { Text false }
      Tag_HeadingPairs {
	Tag_vt:vector size 2 baseType variant {
................................................................................
      Tag_HyperlinksChanged { Text false }
      Tag_AppVersion { Text 1.0 }
    }
    ::ooxml::Dom2zip $zf $root "docProps/app.xml" cd count
    $doc delete

    # docProps/core.xml
    set doc [dom createDocumentNS $xmlns(cp) cp:coreProperties]
    set root [$doc documentElement]

    $root setAttributeNS {} xmlns:dc $xmlns(dc)

    $root setAttributeNS {} xmlns:dcterms $xmlns(dcterms)
    $root setAttributeNS {} xmlns:dcmitype $xmlns(dcmitype)
    $root setAttributeNS {} xmlns:xsi $xmlns(xsi)

    $root appendFromScript {
      Tag_dc:creator { Text $obj(creator) }
      Tag_cp:lastModifiedBy { Text $obj(lastModifiedBy) }
      Tag_dcterms:created xsi:type dcterms:W3CDTF { Text $obj(created) }
      Tag_dcterms:modified xsi:type dcterms:W3CDTF { Text $obj(modified) }
    }
    ::ooxml::Dom2zip $zf $root "docProps/core.xml" cd count
    $doc delete

    # xl/_rels/workbook.xml.rels
    set doc [dom createDocumentNS $xmlns(PR) Relationships]
    set root [$doc documentElement]



    $root appendFromScript {
      for {set ws 1} {$ws <= $obj(sheets)} {incr ws} {
	Tag_Relationship Id rId$ws Type http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet Target worksheets/sheet${ws}.xml {}
      }
      set rId [incr ws -1]
      Tag_Relationship Id rId[incr rId] Type http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme Target theme/theme1.xml {}
      Tag_Relationship Id rId[incr rId] Type http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles Target styles.xml {}
................................................................................
    }
    ::ooxml::Dom2zip $zf $root "xl/_rels/workbook.xml.rels" cd count
    $doc delete


    # xl/sharedStrings.xml
    if {$obj(sharedStrings) > 0} {
      set doc [dom createDocumentNS $xmlns(M) sst]
      set root [$doc documentElement]


      $root setAttribute count [llength $sharedStrings]
      $root setAttribute uniqueCount [llength $sharedStrings]

      $root appendFromScript {
	foreach string $sharedStrings {
	  Tag_si {
	    Tag_t { Text $string }
................................................................................
      ::ooxml::Dom2zip $zf $root "xl/sharedStrings.xml" cd count
      $doc delete
    }


    # xl/calcChain.xml
    if {$obj(calcChain)} {
      set doc [dom createDocumentNS $xmlns(M) calcChain]
      set root [$doc documentElement]



      $root appendFromScript {
	Tag_c r C1 i 3 l 1 {}
	Tag_c r A3 i 2 {}
      }
      ::ooxml::Dom2zip $zf $root "xl/calcChain.xml" cd count
      $doc delete
    }


    # xl/styles.xml
    set doc [dom createDocumentNS $xmlns(M) styleSheet]
    set root [$doc documentElement]

    $root setAttributeNS {} xmlns:mc $xmlns(mc)

    $root setAttributeNS {} xmlns:x14ac $xmlns(x14ac)
    $root setAttribute mc:Ignorable x14ac

    $root appendFromScript {
      if {$obj(numFmts) > $::ooxml::defaults(numFmts,start)} {
	Tag_numFmts count [llength [array names numFmts]] {
	  foreach idx [lsort -integer [array names numFmts]] {
	    Tag_numFmt numFmtId $idx formatCode $numFmts($idx) {}
................................................................................
      Tag_tableStyles count 0 {}
    }
    ::ooxml::Dom2zip $zf $root "xl/styles.xml" cd count
    $doc delete


    # xl/theme/theme1.xml
    set doc [dom createDocumentNS $xmlns(a) a:theme]
    set root [$doc documentElement]


    $root setAttribute name Office-Design

    $root appendFromScript {
      Tag_a:themeElements {
	Tag_a:clrScheme name Office {
	  Tag_a:dk1 {
	    Tag_a:sysClr val windowText lastClr 000000 {}
................................................................................
      Tag_a:extraClrSchemeLst {}
    }
    ::ooxml::Dom2zip $zf $root "xl/theme/theme1.xml" cd count
    $doc delete


    # xl/workbook.xml
    set doc [dom createDocumentNS $xmlns(M) workbook]
    set root [$doc documentElement]

    $root setAttributeNS {} xmlns:r $xmlns(r)


    $root appendFromScript {
      Tag_fileVersion appName xl lastEdited 5 lowestEdited 5 rupBuild 5000 {}
      Tag_workbookPr showInkAnnotation 0 autoCompressPictures 0 {}
      Tag_bookViews {
	Tag_workbookView activeTab 1 {}
      }
................................................................................
    ::ooxml::Dom2zip $zf $root "xl/workbook.xml" cd count
    $doc delete


    # xl/worksheets/sheet1.xml SHEET

    for {set ws 1} {$ws <= $obj(sheets)} {incr ws} {
      set doc [dom createDocumentNS $xmlns(M) worksheet]
      set root [$doc documentElement]

      $root setAttributeNS {} xmlns:r $xmlns(r)
      $root setAttributeNS {} xmlns:mc $xmlns(mc)

      $root setAttributeNS {} xmlns:x14ac $xmlns(x14ac)
      $root setAttribute mc:Ignorable x14ac

      $doc selectNodesNamespaces [list M $xmlns(M) r $xmlns(r) mc $xmlns(mc) ac $xmlns(x14ac)]

      $root appendFromScript {
	Tag_dimension ref [::ooxml::RowColumnToString $obj(dminrow,$ws),$obj(dmincol,$ws)]:[::ooxml::RowColumnToString $obj(dmaxrow,$ws),$obj(dmaxcol,$ws)] {}
	Tag_sheetViews {
	  Tag_sheetView workbookViewId 0 {
	    if {$obj(freeze,$ws) ne {}} {
	      lassign [split [::ooxml::StringToRowColumn $obj(freeze,$ws)] ,] row col
................................................................................
	      Tag_mergeCell ref $item {}
	    }
	  }
	}
	Tag_pageMargins left 0.75 right 0.75 top 1 bottom 1 header 0.5 footer 0.5 {}
      }

      if {[set colsNode [$root selectNodes /M:worksheet/M:cols]] ne {}} {
	if {[info exists obj($ws,cols)] && $obj($ws,cols) > 0} {
	  $colsNode appendFromScript {
	    foreach idx [lsort -dictionary [array names cols $ws,*]] {
	      set attr {}
	      lappend attr min [expr {[dict get $cols($idx) min] + 1}] max [expr {[dict get $cols($idx) max] + 1}]
	      if {[dict get $cols($idx) width] ne {}} {
		lappend attr width [dict get $cols($idx) width]