處理emacs-org模式TODO的一個指令碼

gaorongchao1990626發表於2013-08-25


處理前:



處理後:






1 前言

最近風帆問我一個問題,也就是處理org模式中的TODO。寫一個指令碼, 主要功能是未完成的按照“重要性”與“緊急性”進行分類。然後完成的 任務列出最近一週完成的。感覺還聽有用的,我自己也經常用org模式 所以用了一晚上的時間,寫了這個指令碼,然後上午來了以後由修改了 一下。基本算是可以用了。在寫這個指令碼的過程中,通過遇到的問題 從中又學習了幾點。總結一下,方便後來檢視。

2 中文的處理

Perl處理中文會遇到亂碼的問題。我用的vim編輯器也有編碼的問題。 這裡一併總結一下。

2.1 vim相關

在vim中直接檢視檔案編碼: :set fileencoding
解決vim檢視檔案亂碼的問題:在~/.vimrc中新增一下內容:
let &termencoding=&encoding 
set fileencoding=utf-8,ucs-bom,gbk,cp936
這樣vim就可以自動識別編碼。

2.2 perl 相關

網址:wyllife.blog.163.com/blog/static/4116390120112152541260

Perl實用中文處理步驟(修改版)

2011-03-15 14:05:41| 分類: PERL 相關知識 |字號 訂閱 發信人: FenRagwort (澤), 信區: Perl 標 題: Perl實用中文處理步驟(修改版) 發信站: 水木社群 (Mon Feb 14 12:52:14 2011), 轉信

(修改版 感謝Invader)

0、你至少得知道編碼是怎麼回事,utf-8、gbk是什麼意思 你的文字編輯器能顯示一個檔案是什麼編碼, 不然你要處理中文檔案,都不知道用什麼編碼開啟 不過一般就是gbk和utf8兩種,實在不行兩個都試一遍 注意也許你看到的不是gbk,而是gb2312, 這兩個使用上實際是一樣的,gbk完全包含gb2312

1、讓你的指令碼檔案本身用utf8儲存,最好養成寫任何指令碼都用utf8的習慣

2、指令碼開頭加上: use utf8; use open ":encoding(gbk)", ":std"; 意思是指令碼里的字串都用utf8處理,但是標準輸入輸出用gbk(預設的內碼表編碼) 做到這一步,指令碼里就可以直接用中文了,字串、正規表示式都沒問題

如果要開啟的檔案全部是一種編碼,如utf8,則可以加上: use open ":encoding(utf8)"; #如果檔案全是gbk,那麼承上編碼設定,此行可省略

3.1、開啟內有中文的檔案前,先要確定它的編碼, 最常見是gbk或utf8,臺灣來的可能是big5,utf16le的偶有可能,其他較少見 這樣開啟: open my $fh, "<:encoding(gbk)", "file.txt" or die; # 讀檔案 open my $fh, ">:encoding(utf8)", "file.txt" or die; # 寫檔案

如果Win32系統下開啟utf16le或be檔案,需要寫成: open my $fh, "<:raw:encoding(utf16le):crlf", "file.txt" or die; 否則會有crlf轉換的bug

3.2、也可以先開啟檔案,立刻再用binmode繫結編碼 open my $fh, "file.txt" or die; binmode($fh, ":encoding(gbk)"); 一般情況,直接在open裡指定encoding即可,有時需要先接收資料,再binmode

4、如果你的檔名是中文,有點麻煩,得這樣: use Encode qw/encode/; my $file = "2011年工作記錄.txt"; # 中英文數字混合檔名也沒問題 $file = encode("gbk", $file); # 檔名是通過標準輸出傳給命令列的,而命令列 open my $fh, "<:encoding(gbk)", $file or die;

OK,中文問題搞定了,然後該幹嘛幹嘛,除了一些以位元組為物件的操作(如seek、pack), 你就把“甲乙丙丁”當“ABCD”用吧,冇問題

X、附送小技巧: 如果你是批量處理文字檔案,那甚至可以不管中文檔名問題 比如要處理chfiles資料夾下的所有txt檔案(包含中文檔名),那麼 my @files = glob "chfiles/*.txt"; foreach my $file (@files) { # $file若print出來可能有亂碼,但是無妨 open my $fh, "<:encoding(gbk)", $file or die; while (<$fh>) { print; } }

3 時間相關

直接在下面程式中解釋 包括本地的時間函式localtime,和一個模組,Date::Calc來求兩個時間點的天數差。

4 程式解析

  1:  use strict;
  2:  use warnings;
  3:  use utf8;
  4:  use Encode;
  5:  use open ":encoding(utf8)",":std";
  6:  use Date::Calc qw(Delta_Days);
  7:  use Date::Calc qw(Add_Delta_Days);
  8:  use Data::Dumper;
  9:  
 10:  my (%hash,%hash_finished,$renwu,$start_time);
 11:  my      $in_in = "TODO.org";
 12:  open  my $in, '<', $in_in or die "cannot open\n";
 13:  while(<$in>)
 14:  {
 15:          chomp;
 16:          my $first_line=$_;
 17:          next if /^#/;
 18:          next if /^$/;
 19:          if ($first_line=~m/^\* TODO/)
 20:          {
 21:                  if ($first_line=~m/^\* TODO(.+):重要緊急:/)
 22:                  {
 23:                          $hash{"重要緊急"}{$1}="A";
 24:                  }
 25:                  elsif($first_line=~m/^\* TODO(.+):重要不緊急:/)
 26:                  {
 27:                          $hash{"重要不緊急"}{$1}="A";
 28:                  }
 29:                  elsif($first_line=~m/^\* TODO(.+):不重要緊急:/)
 30:                  {
 31:                          $hash{"不重要緊急"}{$1}="A";
 32:                  }
 33:                  elsif($first_line=~m/^\* TODO(.+):不重要不緊急:/)
 34:                  {
 35:                          $hash{"不重要不緊急"}{$1}="A";
 36:                  }
 37:          }
 38:          elsif($first_line=~/^\* DONE/)
 39:          {
 40:                  $first_line=~/^\* DONE (.+)?\s+:.+:/;
 41:                  $renwu=$1;
 42:                  my $second_line=<$in>;
 43:                  chomp $second_line;
 44:                  $second_line=~m/^CLOSED: \[([-\d]+).+]/;
 45:                  my $third_line=<$in>;
 46:                  $third_line=~m/^.+\[(.+).....]/;
 47:                  $start_time=$1;
 48:                  $hash_finished{$renwu}{$start_time}{$second_line}="A";
 49:          }
 50:  }
 51:  close  $in;
 52:  
 53:  
 54:  my      $out_out = "dayreport.org";
 55:  open  my $out, '>', $out_out or die  "failed open$!\n";
 56:  
 57:  print $out "#+STARTUP: showall\n";
 58:  print $out "#+TITLE:TODO\n";
 59:  print $out "#+HTML_HEAD: <link rel=\"stylesheet\" type=\"text/css\" href=\"todo.css\" />\n";
 60:  print $out "#+OPTIONS: H:3 num:nil toc:nil \\n:t \@:t ::t |:t ^:nil -:t f:t *:t \\<:t\n";
 61:  print $out "#+LANGUAGE: en\n";
 62:  
 63:  =cut
 64:  foreach my $key1 (keys %hash)
 65:  {
 66:          print $out "* $key1\n";
 67:          foreach my $key2 (keys %{$hash{$key1}})
 68:          {
 69:                  print $out "   - $key2\n";
 70:          }
 71:  }
 72:  =cut
 73:  print $out "* 重要緊急\n";
 74:  foreach my $key2 (keys %{$hash{"重要緊急"}})
 75:  {
 76:          $key2=~s/\s+$//;
 77:          print $out "   - $key2\n";
 78:  }
 79:  print $out "* 重要不緊急\n";
 80:  foreach my $key2 (keys %{$hash{"重要不緊急"}})
 81:  {
 82:          $key2=~s/\s+$//;
 83:          print $out "   - $key2\n";
 84:  }
 85:  print $out "* 不重要緊急\n";
 86:  foreach my $key2 (keys %{$hash{"不重要緊急"}})
 87:  {
 88:          $key2=~s/\s+$//;
 89:          print $out "   - $key2\n";
 90:  }
 91:  print $out "* 不重要不緊急\n";
 92:  foreach my $key2 (keys %{$hash{"不重要不緊急"}})
 93:  {
 94:          $key2=~s/\s+$//;
 95:          print $out "   - $key2\n";
 96:  }
 97:  
 98:  #follow is the number of today
 99:  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
100:  $mon=$mon+1;
101:  $year+=1900;
102:  #週一是從週日開始的,要進行一下改動
103:  if ($wday==0)
104:  {
105:          $wday=$wday+7;
106:  }
107:  print $wday;
108:  my %hash_day=(
109:                  週日 => "0",
110:                  週一 => "1",
111:                  週二 => "2",
112:                  週三 => "3",
113:                  週四 => "4",
114:                  週五 => "5",
115:                  週六 => "6",
116:          );
117:  
118:          #用程式計算每週的起止時間,用到Date::Calc模組
119:  my ($monday_year,$monday_mouth,$monday_day);
120:  ($monday_year,$monday_mouth,$monday_day)=Add_Delta_Days($year,$mon,$mday,-$wday+1);
121:  my ($sunday_year,$sunday_mouth,$sunday_day);
122:  ($sunday_year,$sunday_mouth,$sunday_day)=Add_Delta_Days($year,$mon,$mday,7-$wday);
123:  
124:  print $out "\n* 本週已經完成任務: <$monday_year-$monday_mouth-$monday_day>-<$sunday_year-$sunday_mouth-$sunday_day>\n";
125:  foreach my $key1 (keys %hash_finished)
126:  {
127:          foreach my $key2 (keys %{$hash_finished{$key1}})
128:          {
129:                  foreach my $key3 (keys %{$hash_finished{$key1}{$key2}})
130:                  {
131:                          #print "$key3\n";
132:                          $key3=~m/^CLOSED: \[(\d+)-0?(\d+)-0?(\d+) (.+) .+]/;
133:                          my $before_year=$1;
134:                          my $before_mon=$2;
135:                          my $before_mday=$3;
136:                          my $before_weekday=$4;
137:                          #print "$before_weekday\n";
138:                          #用模組來計算兩個時間相差的天數
139:                          my $gap=Delta_Days($before_year,$before_mon,$before_mday,$year,$mon,$mday);
140:                          #print "$gap\n";
141:                          my $weekday=$hash_day{$before_weekday};
142:                          #print "$weekday\n";
143:                          if ($weekday <= $wday and $gap <= 7)
144:                          {
145:                                  $key1=~s/\s+/\t/g;
146:                                  print $out "  - $key1 SCHEDULED:<$key2>\t$key3\n";
147:                          }
148:                          else
149:                          {
150:                                  next;
151:                          }
152:                  }
153:          }
154:  }
155:  
156:  close  $out;

Date: 2013-08-25T21:31+0800

Author: grc

Org version 7.9.3f with Emacs version 24

Validate XHTML 1.0

相關文章