flatten.tcl
Go to the documentation of this file.00001
00002
00003 exec tclsh8.3 "$0" "$@"
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 auto = _path [linsert $auto_path 0 [file dirname [file dirname [file join [pwd] [info script]]]]]
00027
00028
00029 package require xml 2.0
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 ret Process (type data , type type , type out , type args) {
00045 global elementDeclCount PEDeclCount AttListDeclCount CommentCount
00046 global config
00047 set elementDeclCount [set PEDeclCount [set AttListDeclCount [set CommentCount 0]]]
00048
00049 # Create the parser object.
00050 # We want to use the Tcl-only parser for this application,
00051 # because it can resolve entities without doing full
00052 # validation.
00053
00054 set parser [eval ::xml::parser \
00055 -elementstartcommand ElementStart \
00056 -validate 1 \
00057 $args \
00058 ]
00059
00060 if {$config(wantElementDecls)} {
00061 $parser configure -elementdeclcommand [list ElementDeclaration $out]
00062 }
00063 if {$config(wantPEDecls)} {
00064 $parser configure -parameterentitydeclcommand [list PEDecl $out]
00065 }
00066 if {$config(wantAttListDecls)} {
00067 $parser configure -attlistdeclcommand [list AttListDecl $out]
00068 }
00069 if {$config(wantComments)} {
00070 $parser configure -commentcommand [list Comment $out]
00071 }
00072
00073 switch $type {
00074 xml {
00075 # Proceed with normal parsing method
00076 $parser parse $data
00077 }
00078
00079 dtd {
00080 # Use the DTD parsing method instead
00081 $parser parse $data -dtdsubset external
00082 }
00083 }
00084
00085 # Clean up parser object
00086 #$parser free
00087 #rename $parser {}
00088
00089 return {}
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 ret ElementStart (type name , type attlist , type args) {
00106 return -code break
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 ret ElementDeclaration (type out , type name , type cmodel) {
00122 global elementDeclCount
00123 incr elementDeclCount
00124
00125 regsub -all "\[ \t\n\r\]+" $cmodel { } cmodel
00126 puts $out "<!ELEMENT $name $cmodel>"
00127
00128 return {}
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 ret PEDecl (type out , type name , type repl , type args) {
00144 global PEDeclCount
00145 incr PEDeclCount
00146
00147 if {[llength $args]} {
00148 puts $out "<!ENTITY % $name PUBLIC \"[lindex $args 0]\" \"$repl\">"
00149 } else {
00150 puts $out "<!ENTITY % $name \"[string trim $repl]\">"
00151 }
00152
00153 return {}
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 ret AttListDecl (type out , type name , type attname , type type , type dflt , type dfltval) {
00172 global AttListDeclCount
00173 incr AttListDeclCount
00174
00175 puts $out "<!ATTLIST $name $attname $type $dflt $dfltval>"
00176
00177 return {}
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 ret Comment (type out , type data) {
00192 global CommentCount
00193 incr CommentCount
00194
00195 puts $out "<!--${data}-->"
00196
00197 return {}
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 ret Open () {
00211 global currentDir status
00212
00213 set filename [tk_getOpenFile -parent . -title "Open Document" -initialdir $currentDir -defaultextension ".xml" -filetypes {
00214 {{XML Documents} {.xml} }
00215 {{DTD Files} {.dtd} }
00216 {{All File} * }
00217 }]
00218 if {![string length $filename]} {
00219 return {}
00220 }
00221
00222 set currentDir [file dirname $filename]
00223 set savename [file join [file rootname $filename].dtd]
00224 set savename [tk_getSaveFile -parent . -title "Save DTD" -initialdir $currentDir -initialfile $savename -defaultextension ".dtd" -filetypes {
00225 {{XML Documents} {.xml} }
00226 {{DTD Files} {.dtd} }
00227 {{All File} * }
00228 }]
00229 if {![string length $savename]} {
00230 return {}
00231 }
00232
00233 set status Processing
00234 set oldcursor [. cget -cursor]
00235 . configure -cursor watch
00236 grab .elementDecls
00237 update
00238
00239 set ch [open $filename]
00240 set out [open $savename w]
00241 if {[catch {Process [read $ch] [expr {[file extension $filename] == ".dtd" ? "dtd" : "xml"}] $out -baseurl file:
00242
00243 tk_messageBox -message [format [mc {Unable to process document "%s" due to "%s"}] $filename $err] -icon error -default ok -parent . -type ok
00244 } else {
00245 tk_messageBox -message [mc "DTD Saved OK"] -icon info -default ok -parent . -type ok
00246 }
00247
00248 close $ch
00249 close $out
00250 set status {}
00251 grab release .elementDecls
00252 . configure -cursor $oldcursor
00253 return {}
00254 }
00255
00256
00257
00258
00259 package require msgcat
00260 namespace import msgcat::mc
00261 catch {::msgcat::mc
00262
00263
00264
00265
00266
00267
00268
00269
00270 switch [llength $argv] {
00271 0 {
00272 if {![catch {package require Tk}]} {
00273
00274 array config = {wantElementDecls 1 wantPEDecls 0 wantAttlistDecls 1 wantComments 0}
00275 checkbutton .wantElementDecls -variable config(wantElementDecls)
00276 label .elementDeclLabel -text [mc "Element declarations:"]
00277 label .elementDecls -textvariable elementDeclCount
00278 checkbutton .wantPEDecls -variable config(wantPEDecls)
00279 label .peDeclLabel -text [mc "PE declarations:"]
00280 label .peDecls -textvariable PEDeclCount
00281 checkbutton .wantAttListDecls -variable config(wantAttListDecls)
00282 label .attListDeclLabel -text [mc "Atttribute List declarations:"]
00283 label .attListDecls -textvariable AttListDeclCount
00284 checkbutton .wantComments -variable config(wantComments)
00285 label .commentLabel -text [mc "Comments:"]
00286 label .comments -textvariable CommentCount
00287 label .status -textvariable status -foreground red
00288 grid .wantElementDecls .elementDeclLabel .elementDecls
00289 grid .wantPEDecls .peDeclLabel .peDecls
00290 grid .wantAttListDecls .attListDeclLabel .attListDecls
00291 grid .wantComments .commentLabel .comments
00292 grid .status - -
00293 . configure -menu .menu
00294 menu .menu -tearoff 0
00295 .menu add cascade -label [mc File] -menu .menu.file
00296 menu .menu.file
00297 .menu.file add command -label [mc Open] -command Open
00298 .menu.file add separator
00299 .menu.file add command -label [mc Quit] -command exit
00300 currentDir = [pwd]
00301 } else {
00302 Process [read stdin] xml stdout
00303 }
00304 }
00305 default {
00306 foreach filename $argv {
00307 if {$filename == "-"} {
00308 Process [read stdin] xml stdout
00309 } else {
00310 ch = [open $filename]
00311 Process [read $ch] [expr {[file extension $filename] == ".dtd" ? "dtd" : "xml"}] stdout -baseurl file:
00312 close $ch
00313 }
00314 }
00315 }
00316 }
00317