changelog.tcl

Go to the documentation of this file.
00001 /*  changelog.tcl --*/
00002 /* */
00003 /*  Handling of ChangeLog's.*/
00004 /* */
00005 /*  Copyright (c) 2003 Andreas Kupries <andreas_kupries@sourceforge.net>*/
00006 /* */
00007 /*  See the file "license.terms" for information on usage and redistribution*/
00008 /*  of this file, and for a DISCLAIMER OF ALL WARRANTIES.*/
00009 /*  */
00010 /*  RCS: @(#) $Id: changelog.tcl,v 1.5 2005/09/28 04:51:19 andreas_kupries Exp $*/
00011 
00012 
00013 /*  FUTURE -- Expand pre-parsed log (nested lists) into flat structures*/
00014 /*  FUTURE --  => date/author/file/cref + cref/text*/
00015 /*  FUTURE -- I.e. relational/tabular structure, useable in table displays,*/
00016 /*  FUTURE -- sort by date, author, file to see aggregated changes*/
00017 /*  FUTURE --  => Connectivity to 'struct::matrix', Reports!*/
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 /*  ::doctools::changelog::scan --*/
00029 /* */
00030 /*  Scan a ChangeLog generated by 'emacs' and extract the relevant information.*/
00031 /* */
00032 /*  Result*/
00033 /*  List of entries. Each entry is a list of three elements. These*/
00034 /*  are date, author, and commentary. The commentary is a list of*/
00035 /*  sections. Each section is a list of two elements, a list of*/
00036 /*  files, and the associated text.*/
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 /*  ::doctools::changelog::merge --*/
00149 /* */
00150 /*  Merge several preprocessed changelogs (see scan) into one structure.*/
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 /*  ::doctools::changelog::toDoctools --*/
00190 /* */
00191 /*  Convert a preprocessed changelog log (see scan) into a doctools page.*/
00192 /* */
00193 /*  Arguments:*/
00194 /*  evar, cvar, fvar: Name of the variables containing the preprocessed log.*/
00195 /* */
00196 /*  Results:*/
00197 /*  A string containing a properly formatted ChangeLog.*/
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 /*  Module initialization*/
00259 
00260 package provide doctools::changelog 0.1.1
00261 

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1