Documentation of multi-line header arguments.
[org-mode.git] / UTILITIES / make_emacs_changelog
blob8d14a757dd2b471a976e8afe9a4dd04e7a769ea0
1 #!/usr/bin/perl
3 $commitrange = shift @ARGV;
4 if (!$commitrange) {
5 print STDERR "Enter commitrange: ";
6 $commitrange = <>;
7 $commitrange =~ s/\s*(.*?)\s+/$1/;
10 $syncdate = shift @ARGV;
11 if (!$syncdate) {
12 print STDERR "Enter syncdate YYYY-MM-DD: ";
13 $syncdate = <>;
14 $syncdate =~ s/\s*(.*?)\s+/$1/;
17 $kind = shift @ARGV;
18 if (!$kind) {
19 print STDERR 'Enter kind ("lisp" or "texi" or "card" or press RET): ';
20 $kind = <>;
21 $kind =~ s/\s*(.*?)\s+/$1/;
22 $kind =~ s/"(.*?)"/$1/;
25 if ($kind ne "lisp" and $kind ne "texi" and $kind ne "card"
26 and $kind ne "") {
27 die "Invalid Changelog kind";
30 # Run git log to get the commits the messages
31 open IN,"git log $commitrange|";
32 undef $/;
33 $log = <IN>;
34 @commits = split(/^(?=commit)/m,$log);
36 for $i (0..$#commits) {
37 $entry = ""; $tiny = "";
38 $commit = $commits[$i];
39 $author = $1 if $commit=~/^Author: ([^\n]+)/m;
40 $date = $1 if $commit=~/^Date: ([^\n]+)/m;
41 $entry = $1 if $commit=~/^([ \t]*\* [^\f]*?)(\n[ \t]*\n([^*]|\Z)|\Z)/m;
42 $tiny = " (tiny change)" if $commit =~ /TINYCHANGE/;
44 # split author into name and address
45 if ($author =~ /(.*?)\s+(<.*?>)/) {
46 $name = $1;
47 $address = $2;
48 } else {
49 warn "No name/address";
50 next;
53 if ($entry) {
55 # Fix the path when directories have been omitted
57 $entry =~ s/^([ \t]*\* )([-a-zA-Z]+\.el)/$1lisp\/$2/mg;
58 $entry =~ s/^([ \t]*\* )(org[a-z]*\.texi?)/$1doc\/$2/mg;
60 # remove stuff which is not for this output
61 if ($kind =~ /\S/) {
62 remove_parts("contrib/","testing/","xemacs/");
63 remove_parts("Makefile","README");
65 if ($kind eq "lisp") { remove_parts("doc/") }
66 if ($kind eq "texi") { remove_parts("lisp/","doc/orgcard","doc/orgguide") }
67 if ($kind eq "card") { remove_parts("lisp/","doc/org\\.","doc/orgguide") }
69 # indent each line by 1 TAB
70 $entry =~ s/^[ \t]*/\t/gm;
72 # Add empty lines if there are several files in there
73 $entry =~ s/(\n[ \t]+\* )/\n$1/g;
75 # remove blocks of more than one empty line
76 while ($entry =~s/\n[ \t]*\n[ \t]*\n/\n/g) {};
78 # remove/replace parts of the path
80 $entry =~ s/^([ \t]+\* )lisp\//$1/mg;
81 $entry =~ s/^([ \t]+\* )doc\/orgcard/$1 refcards\/orgcard/mg;
82 $entry =~ s/^([ \t]+\* )doc\//$1misc\//mg;
84 # remove empty space at beginning and end
85 $entry =~ s/\A\s*/\t/;
86 $entry =~ s/\s*\Z/\n/;
88 # If there is anything left in the entry, print it
89 if ($entry =~ /\S/) {
90 print "$syncdate $name $address$tiny\n\n$entry\n";
95 sub remove_parts {
96 foreach $path (@_) {
97 $re = "^[ \t]*\\*\\s+" . $path . "[^\\000]*?(?=^[ \\t]*\\*|\\Z)";
98 $entry =~ s/$re/\n$1/mg;