entries_expand_recur.awk (3489B)
1 #!/bin/awk 2 3 function mdy_to_epoch( s ){ 4 d = sprintf( "%s %s %s 00 00 00", substr(s,7,4), substr(s,1,2), substr(s,4,2) ) 5 return mktime( d ) 6 } 7 8 function leapyear( y ){ 9 10 # Determine if y is leap year 11 yy = "Y" 12 13 if ( y/4 ~ int_x ){ 14 y/100 ~ int_x && y/400 !~ int_x ? yy = "Y" : yy = "L" 15 } 16 return yy 17 } 18 19 function set_recur_date( d ){ 20 21 if ( !d ) { exit 1; } 22 23 if ( recur_type == "D" || recur_type == "W" ){ 24 25 d += interval_total 26 27 } else { 28 sy = int(substr( recur_date_mdy, 7, 4 )) 29 sm = int(substr( recur_date_mdy, 1, 2 )) 30 31 if ( recur_type == "M" ) 32 { 33 sx = sm + interval 34 smm = sm 35 while ( sm < sx ) { 36 37 # Check for year change 38 while ( smm > 12 ){ 39 smm -= 12 40 sy++ 41 } 42 43 # If february, check for leap year 44 if ( smm == 2 && leapyear( sy ) == "L" ){ 45 mm = "LM" 46 }else{ 47 mm = smm 48 } 49 50 d += m[m[mm]] 51 sm++ 52 smm++ 53 } 54 55 } else if ( recur_type == "Y" ) 56 { 57 sx = sy + interval 58 while ( sy < sx ) { 59 60 # If after Leap month (2 - february), 61 # check for the next year's leap status 62 # to determine number of days to increment 63 # the year with. 64 sychk = sm > 2 ? sy + 1 : sy 65 mm = leapyear( sychk ) 66 67 #print sy, "Leap with sychk", sychk, "and month", sm, "?", mm 68 d += m[mm] 69 sy++ 70 } 71 } 72 } 73 return d 74 } 75 76 BEGIN{ 77 m[1] = 31 78 m[2] = 28 79 m["LM"] = 29 80 m[3] = 31 81 m[4] = 30 82 m[5] = 31 83 m[6] = 30 84 m[7] = 31 85 m[8] = 31 86 m[9] = 30 87 m[10] = 31 88 m[11] = 30 89 m[12] = 31 90 m[28] = 2419200 91 m[29] = 2505600 92 m[30] = 2592000 93 m[31] = 2678400 94 m["W"] = 604800 95 m["D"] = 86400 96 m["H"] = 3600 97 m["M"] = 60 98 m["L"] = 31622400 99 m["Y"] = 31536000 100 101 int_x = "^[0-9]+$" 102 #dmax_mdy = strftime( "%Y%m%d", dmax ) 103 } 104 105 { 106 #if ( $1 > dmax_mdy ) { exit } 107 $0 = sprintf( "%s <%s", $0, NR) 108 print $0 109 110 # Do some stuff if recurring event 111 # Basically print out all recurrances 112 # up to event max or date max, which 113 # ever earliest 114 115 if ( index( $0, "{" ) > 0 ){ 116 117 recur_a = index( $0, "{" ) 118 recur_b = index( $0, "}" ) 119 split ( substr( $0, recur_a, recur_b - recur_a ), recur, " " ) 120 121 interval = int( substr( recur[1], match(recur[1], /[0-9]+/), RLENGTH ) ) 122 recur_type = toupper( substr(recur[1], match(recur[1], /[ywmdYWMD]{1}/), 1 )) 123 interval_total = m[ recur_type ] * interval 124 125 # If recurring event has max date, get values 126 if ( recur[2] == "->" ){ 127 entry_max = mdy_to_epoch( recur[3] ) 128 }else{ 129 entry_max = dmax 130 } 131 132 recur_date_mdy = $1 133 recur_date = mdy_to_epoch( $1 ) 134 recur_date = set_recur_date( recur_date ) 135 recur_date_mdy = strftime( "%m/%d/%Y", recur_date ) 136 137 if ( match( $0, /^[0-9\/]{10} @ ..:.. -> / ) > 0 ){ 138 recur_date_mdy_b = substr( $0, RLENGTH+1, 10 ) 139 recur_date_b = mdy_to_epoch( recur_date_mdy_b ) 140 recur_date_b = set_recur_date( recur_date_b ) 141 recur_date_mdy_b = strftime( "%m/%d/%Y", recur_date_b ) 142 } 143 144 while (recur_date <= dmax && recur_date <= entry_max) { 145 146 r = $0 147 148 # Replace entry date with recur date 149 gsub( /^[0-9\/]{10}/, recur_date_mdy, r ) 150 ( recur_date_b > 0 ) && gsub( /-> [0-9\/]{10} @/, sprintf("-> %s @", recur_date_mdy_b), r ) 151 152 # Print recurrance 153 print r 154 155 # Set recur_date to next recurrance 156 d = set_recur_date( recur_date ) 157 if ( recur_date == d ) { exit 1 } 158 recur_date = d 159 recur_date_mdy = strftime( "%m/%d/%Y", recur_date ) 160 161 if ( recur_date_b > 0 ){ 162 d = set_recur_date( recur_date_b ) 163 if ( recur_date_b == d ) { exit 1 } 164 recur_date_b = d 165 recur_date_mdy_b = strftime( "%m/%d/%Y", recur_date_b ) 166 } 167 } 168 } 169 }