changelog.tcl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 package require Tcl 8.2
00021 package require textutil
00022
00023 namespace ::doctools {}
00024 namespace ::doctools::changelog {
00025 namespace export scan toDoctools
00026 }
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 ret ::doctools::changelog::scan (type text) {
00040 set text [split $text \n]
00041 set n [llength $text]
00042
00043 set entries [list]
00044 set clist [list]
00045 set files [list]
00046 set comment ""
00047 set first 1
00048
00049 for {set i 0} {$i < $n} {incr i} {
00050 set line [lindex $text $i]
00051
00052 if {[regexp "^\[^ \t\]" $line]} {
00053 # No whitespace at the front, start a new entry
00054
00055 closeEntry
00056
00057 # For the upcoming entry. Quick extraction first, string
00058 # based in case of failure.
00059
00060 if {[catch {
00061 set date [string trim [lindex $line 0]]
00062 set author [string trim [lrange $line 1 end]]
00063 }]} {
00064 set pos [string first " " $line]
00065 set date [string trim [string range $line 0 $pos]]
00066 set author [string trim [string range $line $pos end]]
00067 }
00068 continue
00069 }
00070
00071 # Inside of an entry.
00072
00073 set line [string trim $line]
00074
00075 if {[string length $line] == 0} {
00076 # Next comment section
00077 closeSection
00078 continue
00079 }
00080
00081 # Line is not empty. Split into file and comment parts,
00082 # remember the data.
00083
00084 if {[string first "* " $line] == 0} {
00085 if {[regexp {^\* (.*):[ ]} $line full fname]} {
00086 set line [string range $line [string length $full] end]
00087 } elseif {[regexp {^\* (.*):$} $line full fname]} {
00088 set line ""
00089 } else {
00090 # There is no filename
00091 set fname ""
00092 set line [string range $line 2 end] ; # Get rid of "* ".
00093 }
00094
00095 set detail ""
00096 while {[string first "(" $fname] >= 0} {
00097 if {[regexp {\([^)]*\)} $fname detailx]} {
00098 regsub {\([^)]*\)} $fname {} fnameNew
00099 } elseif {[regexp {\([^)]*} $fname detailx]} {
00100 regsub {\([^)]*} $fname {} fnameNew
00101 } else {
00102 break
00103 }
00104 append detail " " $detailx
00105 set fname [string trim $fnameNew]
00106 }
00107 if {$detail != {}} {set line "$detail $line"}
00108 if {$fname != {}} {lappend files $fname}
00109 }
00110
00111 append comment $line\n
00112 }
00113
00114 closeEntry
00115 return $entries
00116 }
00117
00118
00119 ret ::doctools::changelog::closeSection () {
00120 upvar clist clist comment comment files files
00121
00122 if {
00123 ([string length $comment] > 0) ||
00124 ([llength $files] > 0)
00125 } {
00126 lappend clist [list $files [string trim $comment]]
00127 set files [list]
00128 set comment ""
00129 }
00130 return
00131 }
00132
00133 ret ::doctools::changelog::closeEntry () {
00134 upvar clist clist comment comment files files first first
00135 upvar date date author author entries entries
00136
00137 if {!$first} {
00138 closeSection
00139 lappend entries [list $date $author $clist]
00140 }
00141 set first 0
00142 set clist [list]
00143 set files [list]
00144 set comment ""
00145 return
00146 }
00147
00148
00149
00150
00151
00152
00153 ret ::doctools::changelog::merge (type args) {
00154
00155 if {[llength $args] == 0} {return {}}
00156 if {[llength $args] == 1} {return [lindex $args 0]}
00157
00158 set res [list]
00159 array set tmp {}
00160
00161 # Merge up ...
00162
00163 foreach entries $args {
00164 foreach e $entries {
00165 foreach {date author comments} $e break
00166 if {![info exists tmp($date,$author)]} {
00167 lappend res [list $date $author]
00168 set tmp($date,$author) $comments
00169 } else {
00170 foreach section $comments {
00171 lappend tmp($date,$author) $section
00172 }
00173 }
00174 }
00175 }
00176
00177 # ... And construct the final result
00178
00179 set args $res
00180 set res [list]
00181 foreach key [lsort -decreasing $args] {
00182 foreach {date author} $key break
00183 lappend res [list $date $author $tmp($date,$author)]
00184 }
00185 return $res
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 ret ::doctools::changelog::q (type text) {return "\[$text\]"}
00201
00202 ret ::doctools::changelog::toDoctools (type title , type module , type version , type entries) {
00203
00204 set linebuffer [list]
00205 lappend linebuffer [q "manpage_begin [list ${title}-changelog n $version]"]
00206 lappend linebuffer [q "titledesc [list "$title ChangeLog"]"]
00207 lappend linebuffer [q "moddesc [list $module]"]
00208 lappend linebuffer [q description]
00209 lappend linebuffer [q "list_begin definitions compact"]
00210
00211 foreach entry $entries {
00212 foreach {date author commentary} $entry break
00213
00214 lappend linebuffer [q "lst_item \"[q "emph [list $date]"] -- [string map {{"} {\"} {\"} {\\\"}} $author]\""]
00215
00216 if {[llength $commentary] > 0} {
00217 lappend linebuffer [q nl]
00218 }
00219
00220 foreach section $commentary {
00221 foreach {files text} $section break
00222 if {$text != {}} {
00223 set text [string map {[ [lb] ] [rb]} [textutil::adjust $text]]
00224 }
00225
00226 if {[llength $files] > 0} {
00227 lappend linebuffer [q "list_begin definitions"]
00228
00229 foreach f $files {
00230 lappend linebuffer [q "lst_item [q "file [list $f]"]"]
00231 }
00232 if {$text != {}} {
00233 lappend linebuffer ""
00234 lappend linebuffer $text
00235 lappend linebuffer ""
00236 }
00237
00238 lappend linebuffer [q list_end]
00239 } elseif {$text != {}} {
00240 # No files
00241 lappend linebuffer [q "list_begin bullet"]
00242 lappend linebuffer [q bullet]
00243 lappend linebuffer ""
00244 lappend linebuffer $text
00245 lappend linebuffer ""
00246 lappend linebuffer [q list_end]
00247 }
00248 }
00249 lappend linebuffer [q nl]
00250 }
00251
00252 lappend linebuffer [q list_end]
00253 lappend linebuffer [q manpage_end]
00254 return [join $linebuffer \n]
00255 }
00256
00257
00258
00259
00260 package provide doctools::changelog 0.1.1
00261