[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[原创代码] [Perl]终端版信息整理、分类、浏览工具(个人Wiki)

本帖最后由 523066680 于 2015-8-18 22:38 编辑

【我的Perl脚本不管有没有卵用还是要发布的系列】

实质上是一个多重HSAH结构的编辑、浏览工具,ID那个没有搞加密,存储密码的时候暂时用助记码或者密码提醒。




ActivePerl V5.16, Win32,  需要安装模块:YAML
而 Win32::Console 为 ActivePerl自带
选择YAML是因为即使没有这个工具,直接打开YAML文件也可以直观的浏览信息

脚本保存为UTF-8文本格式,反正就是很长不改了哈哈哈
  1. =info
  2.   523066680
  3.   2015-08-18
  4. =cut
  5. use utf8;
  6. use strict;
  7. no strict 'refs';
  8. use Time::HiRes 'sleep';
  9. use IO::Handle;
  10. use Encode;
  11. use Data::Dumper;
  12. STDOUT->autoflush(1);
  13. use Win32::Console;
  14. our $env_ref;
  15. our $env_ref_name;
  16. our ($MAX_COL, $MAX_LINE) = (120, 30);
  17. our $MATRIX = $MAX_COL * $MAX_LINE;
  18. our $IN = Win32::Console->new(STD_INPUT_HANDLE);
  19. our $OUT= Win32::Console->new(STD_OUTPUT_HANDLE);
  20. system("mode con cols=$MAX_COL");
  21. $OUT->Window(1, 0, 0, 119, 29);
  22. our $IN_DEFAULT = $IN->Mode();
  23. our $File;
  24. $File=encode('gbk', "D:\\备忘录.yaml");
  25. $OUT->Cursor(1, 1, 99, 1);  #这里设置了光标高度,后面就不需要再设置了。
  26.                             #如果后面每次都指定了高度,则光标会闪烁频繁以至于移动时看不见
  27. $IN->Mode(ENABLE_MOUSE_INPUT);
  28. $OUT->FillAttr($FG_WHITE | $BG_CYAN, $MATRIX, 0, 0);  #背景填充,0, 0为起点
  29. my %hash;
  30. my @info;
  31. =info Struct
  32.     存储不同层次下的菜单列表信息
  33.     @info = (
  34.         {                  # ---> level 0
  35.             "key1" =>
  36.             {   x    =>value,
  37.                 light=>bool,
  38.                 str  =>keyname,
  39.                 ref  =>self
  40.                 y    =>value,
  41.                 length => strlen
  42.             },
  43.             "key2" => {},
  44.             "key3" => {},
  45.         },
  46.         {                  # ---> level 1
  47.             "key1/name1" => {},
  48.             "key1/name2" => {},
  49.             ...
  50.         },
  51.     )
  52. =cut
  53. &load_data(\%hash, $File);
  54. GO_BACK:
  55. #首列
  56. our @indent=(1);
  57. @info=();
  58. $indent[1] = &expand(\%hash, \%{$info[0]}, "", $indent[0]);  #first key=""
  59. our @prev=();
  60. our $INDENT = 2;   #统一缩进量
  61. my ($mx, $my);
  62. my $BackupRect;
  63. my $max_level=6;
  64. my $cur_level=0;
  65. GO_CONTINUE:
  66. while (1)
  67. {
  68.     sleep 0.02;
  69.     my @arr = $IN->Input();
  70.     my $inside;
  71.     if ($arr[0]==2) #arr[0] -> key or mouse, [1] -> mouse x, [2] -> mouse y
  72.     {
  73.         ($mx, $my) = ($arr[1], $arr[2]);
  74.         $inside = 0;
  75.         for my $i (0 .. $max_level)     # 0,1,2代表列表的层次
  76.         {
  77.             my $j = $i+1;
  78.             for my $path (keys %{$info[$i]})   #这个$path是fullpath的
  79.             {
  80.                 #如果位于某个条目并且状态并非高亮 -> 切换到高亮并显示下一级条目
  81.                 if ( inItem( $info[$i]{$path}, @arr[1,2]  ) )
  82.                 {
  83.                     $inside++;
  84.                 }
  85.                 if (  inItem( $info[$i]{$path}, @arr[1,2] )
  86.                                 and
  87.                         $info[$i]{$path}{light}==0  )
  88.                 {
  89.                     #加一句cursor 0,0 似乎能阻止条目高亮出现缺口
  90.                     $OUT->Cursor(0,0);
  91.                     HighLightItem( $info[$i]{$path} );
  92.                     #清理次级高亮条目 (首层的光标改变时), 放在expand之前执行,
  93.                     if (defined $prev[$j])
  94.                     {
  95.                         ClearLight( $info[$j]{$prev[$j]} );
  96.                         undef $prev[$j];
  97.                         for my $clear ($j..$max_level)
  98.                         {
  99.                             undef %{$info[$clear]};
  100.                         }
  101.                     }
  102.                     $indent[$j+1] =
  103.                         expand(
  104.                             $info[$i]{$path}{'self'},   #当前对象
  105.                             $info[$j],                  #设置下一级菜单
  106.                             $path,                      #完整path
  107.                             $indent[$j]+$INDENT         #缩进量
  108.                         );
  109.                     #移除当前条目上一次的光标
  110.                     ClearLight( $info[$i]{$prev[$i]} );
  111.                     $prev[$i]=$path;
  112.                 }
  113.                 #显示信息摘要
  114.                 if ( inDetail($info[$i]{$path}, @arr[1,2]) )
  115.                 {
  116.                     show_info(
  117.                         $info[$i]{$path},
  118.                         $indent[$j]+$INDENT,
  119.                         \$BackupRect
  120.                     );
  121.                 }
  122.                 #单击鼠标左键时显示所有详细信息
  123.                 if ( inItem($info[$i]{$path}, @arr[1,2]) and $arr[3]==1 )
  124.                 {
  125.                     show_detail( $info[$i]{$path}{'self'} );
  126.                 }
  127.                 #右键菜单
  128.                 if ( inItem($info[$i]{$path}, @arr[1,2]) and $arr[3]==2 )
  129.                 {
  130.                     #MARK_1 取消清理子键信息
  131.                     #在调用菜单事件之前,清理子键信息
  132.                     for my $clear ($j..$max_level)
  133.                     {
  134.                         #undef %{$info[$clear]};
  135.                     }
  136.                     context_menu(
  137.                         $indent[$j], $arr[2], $info[$i], $path, $i
  138.                     );
  139.                         #缩进        坐标     当前级$info 绝对路径
  140.                 }
  141.             }
  142.         }
  143.         if ($inside > 0)
  144.         {
  145.         }
  146.         $OUT->Cursor($mx, $my);
  147.     } elsif ($arr[0]==1 and $arr[1]==1 and $arr[5]==27) {
  148.         &save(\%hash, $File);
  149.         $OUT->Cls();
  150.         exit;
  151.     } elsif ($arr[0]==1 and $arr[1]==1 and lc(chr($arr[5])) eq 's') {
  152.         &save(\%hash, $File);
  153.         wrong("", "save!");
  154.     } elsif ($arr[0]==1 and $arr[1]==1 and $arr[3]==116) {  #F5 刷新界面从头开始
  155.         goto GO_BACK;
  156.     }
  157. }
  158. sub expand
  159. {
  160.     my ($ref, $info, $parent, $indent) = @_;
  161.     my ($cx, $cy) = ( $indent, 1 );
  162.     ClearRect($cx, $MAX_COL, 1, $MAX_LINE);
  163.     my $mark;
  164.     my $max=0;
  165.     my $len=0;
  166.     my @fold;
  167.     my @file;
  168.     %$info=();
  169.     my $tkid;
  170.     foreach my $kid (sort keys %$ref)
  171.     {
  172.         next if ($kid eq 'note');     #跳过笔记标记
  173.         $tkid = $kid;
  174.         $mark = $parent .":". $kid;
  175.         $tkid =~s/^\d_//;             #去掉编号信息
  176.         
  177.         if ( (keys %{$ref->{$kid}} ) > 1 )
  178.         {
  179.             $tkid = "/". $tkid;
  180.             push @fold, $mark;
  181.         } else {
  182.             push @file, $mark;
  183.         }
  184.         $tkid = " $tkid ";
  185.         $len = length($tkid);
  186.         $max = $len if ( $len > $max );
  187.         $$info{$mark} = {       # key name使用完整路径
  188.             "x"     => $cx,     # 由于@fold和@file分开列出,所以$cy在后面排列时设置
  189.             "light" => 0,       # 高亮状态
  190.             "str"   => $tkid,   # 用于显示的keyname
  191.             "self"  => $ref->{$kid},   # 该key的引用
  192.             "parent"=> $ref,
  193.         };
  194.     }
  195.     foreach ( @fold, @file)
  196.     {   
  197.         $$info{$_}{"y"} = $cy++;
  198.         $$info{$_}{"length"} = $max;
  199.         $OUT->Cursor($$info{$_}{x}, $$info{$_}{y});
  200.         $OUT->Write($$info{$_}{str});
  201.         $OUT->FillAttr(
  202.             $FG_WHITE|$BG_CYAN,
  203.             $$info{$_}{length},
  204.             $$info{$_}{x},
  205.             $$info{$_}{y}
  206.         );
  207.     }
  208.     return $max+$indent;
  209. }
  210. sub show_detail
  211. {
  212.     my $item_ref = shift;
  213.     my @arr;
  214.     my $BACKUP;
  215.     my $tmpstr;
  216.     $BACKUP = $OUT->ReadRect(1, 1, $MAX_COL, $MAX_LINE);
  217. SHOW:
  218.     $OUT->Cls();
  219.     $OUT->Cursor(0,1);    #从第一行开始写信息
  220.     my @detail;
  221.     $tmpstr = join("\n", @{ $item_ref->{'note'} });
  222.     if ($tmpstr=~/\t[^\t]+\t/)
  223.     {
  224.         @detail = &tabformat( $item_ref->{'note'} );
  225.         print join("\n", @detail);
  226.     } else {
  227.         print $tmpstr;
  228.     }
  229.     my $inp;
  230.     while (1)
  231.     {
  232.         sleep 0.1;
  233.         @arr=$IN->Input();
  234.         if ($arr[0]==1 and $arr[5]==27) {
  235.             last;
  236.         } elsif ($arr[0]==1 and $arr[3]==17) {  #control
  237.             $inp = inputBar( $item_ref );
  238.             $OUT->Cursor(0, 0);
  239.             goto SHOW;
  240.         }
  241.     }
  242.     $OUT->Cls();
  243.     $OUT->FillAttr($FG_WHITE | $BG_CYAN, $MATRIX, 0, 0);
  244.     $OUT->WriteRect($BACKUP, 1, 1, $MAX_COL, $MAX_LINE);
  245. }
  246. sub show_info
  247. {
  248.     my ($info, $indent, $PREV_RECT) = @_;
  249.     my ($mx, $my);
  250.     my @arr=();
  251.     my $inity = 8;
  252.     my ($cx, $cy)=($indent, $inity);
  253.     my $col_area = $MAX_COL - $indent - 1;  #比最大边界少1
  254.     my $line_area = $MAX_LINE - $cy;
  255.     $PREV_RECT = $OUT->ReadRect($cx, $cy, $MAX_COL, $MAX_LINE);
  256.     &ClearRect($cx, $MAX_COL, $cy, $MAX_LINE);
  257.     my $i = 0;
  258.     my $tmpstr;
  259.     my $nn;
  260.     my @detail;
  261.     my @notes;
  262.     if ( exists $info->{'self'}{'note'} )
  263.     {
  264.         @notes = @{ $info->{'self'}{'note'} };
  265.     }
  266.     else
  267.     {
  268.         @notes = ();
  269.     }
  270.     $tmpstr=join("\n", @notes );
  271.     if ($tmpstr=~/\t[^\t]+\t/)
  272.     {
  273.         @detail = tabformat( \@notes );
  274.     }
  275.     foreach ( @notes )
  276.     {
  277.         $i++;
  278.         $nn=sprintf("%02d ",$i);
  279.         if ($#detail < 0) {
  280.             $tmpstr=$_;
  281.             $tmpstr=~s/\t/ /g;
  282.             $tmpstr=substr($nn . $tmpstr, 0, $col_area);
  283.         } else {
  284.             $tmpstr=substr($nn . $detail[$i-1], 0, $col_area);
  285.         }
  286.         $OUT->Cursor($cx, $cy);
  287.         $OUT->Write( $tmpstr );
  288.         $OUT->FillAttr($FG_YELLOW|$BG_CYAN, $col_area, $cx, $cy++);
  289.         last if ($cy >= ($MAX_LINE-1));
  290.     }
  291.    
  292.     if ($i==0)
  293.     {
  294.         $OUT->Cursor($cx, $cy);
  295.         $OUT->Write("There is nothing");
  296.         $OUT->FillAttr($FG_YELLOW|$BG_CYAN, $col_area, $cx, $cy);
  297.     }
  298.     #循环:当鼠标移开时恢复原来的信息
  299.     my ($x, $y, $len) = (
  300.         $info->{'x'},
  301.         $info->{'y'},
  302.         $info->{'length'}
  303.     );
  304.     while (1)
  305.     {
  306.         sleep 0.03;
  307.         @arr=$IN->Input();
  308.         if ($arr[0]==2)        #0 => key/mouse, 1 => x, 2 => y
  309.         {   
  310.             ($mx, $my) = ($arr[1], $arr[2]);
  311.             $OUT->Cursor($mx, $my);
  312.             if (not inDetail( $info, $mx, $my) )
  313.             {
  314.                 $OUT->WriteRect($PREV_RECT, $cx, $inity, $MAX_COL, $MAX_LINE);
  315.                 last;
  316.             }
  317.         }
  318.     }
  319. }
  320. FILL_CLEAR: {
  321.     sub ClearLight
  322.     {
  323.         my $hash = shift;
  324.         $OUT->FillAttr($FG_WHITE | $BG_CYAN, $$hash{length}, $$hash{x}, $$hash{y});
  325.         $$hash{light}=0;
  326.     }
  327.     sub ClearLight_menu
  328.     {
  329.         my $hash = shift;
  330.         $OUT->FillAttr($FG_YELLOW | $BG_BLUE, $$hash{length}, $$hash{x}, $$hash{y});
  331.         $$hash{light}=0;
  332.     }
  333.     sub ClearRect
  334.     {
  335.         my ($left, $right, $top, $bottom) = @_;
  336.         my $delta=$right-$left;
  337.         foreach ($top..$bottom) {
  338.             $OUT->FillChar(" ", $delta, $left, $_);
  339.             $OUT->FillAttr($FG_WHITE | $BG_CYAN, $delta, $left, $_);
  340.         }
  341.     }
  342.     sub ClearRect_byColor
  343.     {
  344.         my ($color, $left, $right, $top, $bottom) = @_;
  345.         my $delta = $right - $left;
  346.         foreach ($top .. $bottom) {
  347.             $OUT->FillChar(" ", $delta, $left, $_);
  348.             $OUT->FillAttr($color, $delta, $left, $_);
  349.         }
  350.     }
  351.     sub fill_line
  352.     {
  353.         my ($str, $length, $attr, $line) = @_;
  354.         $OUT->FillChar($str, $length, 0, $line);
  355.         $OUT->FillAttr($attr, $length, 0, $line);
  356.     }
  357.     sub HighLightItem
  358.     {
  359.         my $info_ref = shift;
  360.         $OUT->FillAttr(
  361.             $FG_BLACK | $BG_WHITE,
  362.             $info_ref->{length},
  363.             $info_ref->{x},
  364.             $info_ref->{y}
  365.         );
  366.         $info_ref->{light}=1;
  367.     }
  368. }
  369. sub context_menu
  370. {
  371.     #调用注释
  372.     #  ReadRect和WriteRect 的时候,指定的是区域坐标。采用$dtx
  373.     #  ClearRect 和 FillAttr ,指定的是实际长度,所以用$col_area
  374.     my @arr;
  375.     my ($initx, $inity, $info, $path, $lv) = @_;
  376.     my @menu;
  377.     my @menu_inf = ();
  378.     my $menus =
  379.     {
  380.         '0_添加目录' => 'add_item',
  381.         '1_重命名' => 'rename_item',
  382.         '2_复制' => 'copy_tree',
  383.         '3_粘贴' => 'paste_tree',
  384.         '4_删除' => 'delete_item',
  385.         '2_信息' => {
  386.             '0_编辑' => 'edit_notes',
  387.             '0_复制' => 'copy_to_clip',
  388.             '1_粘贴' => 'append_from_clip',
  389.             '2_清除' => 'delete_notes',
  390.             '3_+BANK' => 'BANK_to_notes',
  391.             '3_+ID'   => 'ID_to_notes',
  392.         },
  393.         
  394.         '3_新建' => {
  395.             '1_Normal' => 'add_sub_item',
  396.             '2_ID' => 'add_sub_item_ID',
  397.             '3_Bank' => 'add_sub_item_BANK',
  398.             '4_Date' => 'add_date_item',
  399.         },
  400.     };
  401.     #记录 并清理从左往右的区域
  402.     my $PREV_RECT = $OUT->ReadRect(
  403.             $initx, 1, $MAX_COL, $MAX_LINE
  404.         );
  405.     ClearRect($initx, $MAX_COL, 1, $MAX_LINE);
  406.     my @prev;
  407.     my @indent;
  408.     my $j;
  409.     my $max_level = 4;
  410.     $indent[0] = $initx + 1;  #避免和原标签冲突(原标签预留2个字节位置用于显示概要)
  411.     $indent[1] =
  412.         expand_menu($menus, \%{$menu_inf[0]}, "", $indent[0], $inity);  #显示菜单并记录菜单信息
  413. CONTEXT_WHILE: while (1)
  414.     {
  415.         sleep 0.03;
  416.         @arr = $IN->Input();
  417.         my $inside = 0;
  418.         if ($arr[0] == 2)   #鼠标操作
  419.         {
  420.             ($mx, $my) = ($arr[1], $arr[2]);
  421.             
  422.             for my $i (0..$max_level)     # 0,1,2代表列表的层次
  423.             {
  424.                 $j = $i+1;
  425.                 for my $m_path (keys %{$menu_inf[$i]})   #这个$path是fullpath的
  426.                 {
  427.                     #如果位于某个条目并且状态并非高亮 -> 切换到高亮并显示下一级条目
  428.                     if (  inItem( $menu_inf[$i]{$m_path}, @arr[1,2] )) {
  429.                         $inside++;
  430.                         #单击鼠标左键且该选项指向一个函数
  431.                         if ( $arr[3]==1 and defined $menu_inf[$i]{$m_path}->{'func'} )
  432.                         {
  433.                             &{ $menu_inf[$i]{$m_path}->{'func'} }(
  434.                                 $$info{$path}{'parent'}, $path, $lv
  435.                             );
  436.                             last CONTEXT_WHILE;
  437.                         }
  438.                     }
  439.                     if (
  440.                         inItem( $menu_inf[$i]{$m_path}, @arr[1,2] )
  441.                                     and
  442.                             $menu_inf[$i]{$m_path}{light}==0  
  443.                     )
  444.                     {
  445.                         #清理次级高亮条目 (首层的光标改变时), 放在expand之前执行,
  446.                         if ( defined $prev[$j] )
  447.                         {
  448.                             #ClearLight_menu( $menu_inf[$j]{$prev[$j]} );
  449.                             undef $prev[$j];
  450.                             for my $clear ($j..$max_level)
  451.                             {
  452.                                 undef %{$menu_inf[$clear]};
  453.                             }
  454.                         }
  455.                         $indent[$j+1] =
  456.                             expand_menu(
  457.                                 $menu_inf[$i]{$m_path}{'self'},   #当前对象
  458.                                 $menu_inf[$j],                    #设置下一级菜单
  459.                                 $m_path,                          #完整path
  460.                                 $indent[$j]+1,                    #缩进量
  461.                                 $my
  462.                             );
  463.                         #移除当前条目上一次的光标
  464.                         ClearLight_menu( $menu_inf[$i]{$prev[$i]} );
  465.                         HighLightItem( $menu_inf[$i]{$m_path} );
  466.                         $prev[$i]=$m_path;
  467.                     }
  468.                 }
  469.             }
  470.         }
  471.         #$OUT->Cursor( ($IN->Input())[1,2]);  #恢复光标位置
  472.         #如果鼠标位置不在条目内,以及不在path条目位置,退出菜单循环
  473.         if ($inside == 0 and ( not inItem( $$info{$path}, @arr[1,2])) )
  474.         {
  475.             last; # CONTEXT_WHILE;
  476.         }
  477.     }
  478.     $OUT->WriteRect($PREV_RECT, $initx, 1, $MAX_COL, $MAX_LINE);
  479. }
  480. sub expand_menu
  481. {
  482.     my ($ref, $info, $parent, $indent, $cy) = @_;
  483.     my $cx = $indent;
  484.     my $mark;
  485.     my $max=0;
  486.     my $len=0;
  487.     my @fold;    #fold 和file的作用是含子菜单和不含子菜单的先后分开列出。避免混乱显示
  488.     my @file;
  489.     ClearRect($cx, $MAX_COL, 1, $MAX_LINE);  #从首行开始清理(0行留给提示信息)
  490.     %$info=();
  491.     my $tkid;
  492.     foreach my $kid (sort keys %$ref)
  493.     {
  494.         next if ($kid eq 'note');
  495.         $tkid = encode('gbk', $kid);
  496.         $tkid =~s/\d_//;  #去掉编号信息
  497.         $mark = $parent .":". $kid;
  498.         
  499.         
  500.         if ( (keys %{$ref->{$kid}} ) > 0 )  #目录
  501.         {
  502.             $tkid = " $tkid ->";
  503.             push @fold, $mark;
  504.         } else {
  505.             $tkid = " $tkid ";
  506.             push @file, $mark;
  507.         }
  508.         $len = length($tkid);
  509.         $max = $len if ( $len > $max );
  510.         $$info{$mark} = {       # key name使用完整路径
  511.             "x"     => $cx,     # 由于@fold和@file分开列出,所以$cy在后面排列时设置
  512.             "light" => 0,       # 高亮状态
  513.             "str"   => $tkid,   # 用于显示的keyname
  514.             "self"  => $ref->{$kid},   # 该key的引用
  515.             "parent"=> $ref,
  516.         };
  517.         if ( (keys %{$ref->{$kid}} ) == 0 )
  518.         {
  519.             $$info{$mark}{'func'} = \&{ $ref->{$kid} };
  520.         }
  521.     }
  522.     foreach ( @fold, @file )
  523.     {
  524.         $$info{$_}{"y"} = $cy++;
  525.         $$info{$_}{"length"} = $max;
  526.         $OUT->Cursor($$info{$_}{x}, $$info{$_}{y});
  527.         $OUT->Write($$info{$_}{str}."\b");
  528.         $OUT->FillAttr(
  529.             $FG_YELLOW|$BG_BLUE,
  530.             $$info{$_}{length},
  531.             $$info{$_}{x},
  532.             $$info{$_}{y}
  533.         );
  534.     }
  535.     return $max+$indent;
  536. }
  537. MENU_FUNC:
  538. {
  539.     sub add_item
  540.     {
  541.         our @prev;
  542.         our @indent;
  543.         my ($parent_ref, $path, $lv) = @_;
  544.         my $newkey;
  545.         $newkey = &lineInput();
  546.         return 0 if ($newkey eq 'exit');
  547.         if ( exists $parent_ref->{"$newkey"} )
  548.         {
  549.             wrong("", "key exists");
  550.             return 0;   
  551.         }
  552.         $parent_ref->{"$newkey"} = {
  553.             'note' => [],
  554.         };
  555.         undef $prev[$lv];               #取消上一次高亮菜单的记录
  556.         my $adjust;
  557.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  558.         $indent[$lv+1] =
  559.             expand($parent_ref, $info[$lv], $path, $indent[$lv]+$adjust);
  560.         
  561.         goto GO_CONTINUE;
  562.     }
  563.     sub add_sub_item
  564.     {
  565.         our @prev;
  566.         our @indent;
  567.         my ($parent_ref, $path, $lv) = @_;
  568.         my $newkey;
  569.         my $last_key;
  570.         $newkey = &lineInput();
  571.         return 0 if ($newkey eq 'exit');
  572.         $path=~/:([^:]+)$/;        #提取子键
  573.         $last_key = $1;
  574.         if ( exists $parent_ref->{$last_key}{$newkey} )
  575.         {
  576.             wrong("", "key exists");
  577.             return 0;   
  578.         }
  579.         $parent_ref->{$last_key}{$newkey} = {
  580.             'note'=>[],
  581.         };
  582.         undef $prev[$lv];               #取消上一次高亮菜单的记录
  583.         my $adjust;
  584.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  585.         $indent[$lv+1] =
  586.             expand($parent_ref, $info[$lv], $path, $indent[$lv]+$adjust);
  587.         goto GO_CONTINUE;
  588.     }
  589.     sub add_date_item
  590.     {
  591.         our @prev;
  592.         our @indent;
  593.         my ($parent_ref, $path, $lv) = @_;
  594.         my $newkey;
  595.         my $last_key;
  596.         $newkey = get_date();
  597.         $path=~/:([^:]+)$/;        #提取子键
  598.         $last_key = $1;
  599.         if ( exists $parent_ref->{$last_key}{$newkey} )
  600.         {
  601.             wrong("", "key exists");
  602.             return 0;   
  603.         }
  604.         $parent_ref->{$last_key}{$newkey} = {
  605.             'note'=>[],
  606.         };
  607.         undef $prev[$lv];               #取消上一次高亮菜单的记录
  608.         my $adjust;
  609.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  610.         $indent[$lv+1] =
  611.             expand($parent_ref, $info[$lv], $path, $indent[$lv]+$adjust);
  612.         goto GO_CONTINUE;
  613.     }
  614.     sub add_sub_item_BANK
  615.     {
  616.         our @prev;
  617.         our @indent;
  618.         my ($parent_ref, $path, $lv) = @_;
  619.         my $newkey;
  620.         my $last_key;
  621.         $newkey = &lineInput();
  622.         return 0 if ($newkey eq 'exit');
  623.         $path=~/:([^:]+)$/;        #提取子键
  624.         $last_key = $1;
  625.         if ( exists $parent_ref->{$last_key}{$newkey} )
  626.         {
  627.             wrong("", "key exists");
  628.             return 0;   
  629.         }
  630.         $parent_ref->{$last_key}{$newkey} = {
  631.             'note' => [
  632.                 encode('gbk', " "x4 . " 开行点: "),
  633.                 encode('gbk', " "x4 . "   姓名: "),
  634.                 encode('gbk', " "x4 . "   卡号: "),
  635.                 encode('gbk', " "x4 . " 登录名: "),
  636.                 encode('gbk', " "x4 . "passkey: "),
  637.                 encode('gbk', " "x4 . "   code: "),
  638.                 encode('gbk', " "x4 . " USBKey: "),
  639.                 encode('gbk', " "x4 . "   mark: "),
  640.                 encode('gbk', " "x4 . "   date: "),
  641.             ],
  642.         };
  643.         undef $prev[$lv];               #取消上一次高亮菜单的记录
  644.         my $adjust;
  645.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  646.         $indent[$lv+1] =
  647.             expand($parent_ref, $info[$lv], $path, $indent[$lv]+$adjust);
  648.         goto GO_CONTINUE;
  649.     }
  650.     sub add_sub_item_ID
  651.     {
  652.         our @prev;
  653.         our @indent;
  654.         my ($parent_ref, $path, $lv) = @_;
  655.         my $newkey;
  656.         my $last_key;
  657.         $newkey = &lineInput();
  658.         return 0 if ($newkey eq 'exit');
  659.         $path=~/:([^:]+)$/;        #提取子键
  660.         $last_key = $1;
  661.         if ( exists $parent_ref->{$last_key}{$newkey} )
  662.         {
  663.             wrong("", "key exists");
  664.             return 0;   
  665.         }
  666.         $parent_ref->{$last_key}{$newkey} = {
  667.             'note' => [
  668.                             '  website: ',
  669.                             '   E-mail: ',
  670.               encode('gbk', '       ID: '),
  671.               encode('gbk', '     昵称: '),
  672.               encode('gbk', ' 密码提示: '),
  673.               encode('gbk', '    问题1: '),
  674.               encode('gbk', '    答案1: '),
  675.               encode('gbk', '    问题2: '),
  676.               encode('gbk', '    答案2: '),
  677.               encode('gbk', '    其他 : '),
  678.             ],
  679.         };
  680.         undef $prev[$lv];               #取消上一次高亮菜单的记录
  681.         my $adjust;
  682.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  683.         $indent[$lv+1] =
  684.             expand($parent_ref, $info[$lv], $path, $indent[$lv]+$adjust);
  685.         goto GO_CONTINUE;
  686.     }
  687.     sub rename_item
  688.     {
  689.         our @prev;
  690.         our @indent;
  691.         my ($parent_ref, $path, $lv) = @_;
  692.         my $newkey;
  693.         my $last_key;
  694.         $newkey = &lineInput();
  695.         return 0 if ($newkey eq 'exit');
  696.         $path=~/:([^:]+)$/;        #提取子键
  697.         $last_key = $1;
  698.         $parent_ref->{$newkey} = $parent_ref->{ $last_key };
  699.         delete $parent_ref->{$last_key};
  700.         undef $prev[$lv];               #取消上一次高亮菜单的记录
  701.         my $adjust;
  702.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  703.         $indent[$lv+1] =
  704.             expand($parent_ref, $info[$lv], $path, $indent[$lv]+$adjust);
  705.         
  706.         goto GO_CONTINUE;
  707.     }
  708.     sub delete_item
  709.     {
  710.         our @prev;
  711.         our @indent;
  712.         my ($parent_ref, $path, $lv) = @_;
  713.         my $adjust;
  714.         $path=~/:([^:]+)$/;        #提取子键
  715.         delete $parent_ref->{$1};
  716.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  717.         $indent[$lv+1] =
  718.             expand($parent_ref, $info[$lv], $path, $indent[$lv]+$adjust);
  719.         
  720.         goto GO_CONTINUE;
  721.     }
  722.     sub copy_tree
  723.     {
  724.         our @prev;
  725.         our @indent;
  726.         our $env_ref;
  727.         our $env_ref_name;
  728.         my ($parent_ref, $path, $lv) = @_;
  729.         my $adjust;
  730.         $path=~/:([^:]+)$/;
  731.         $env_ref_name = $1;
  732.         $env_ref = $parent_ref->{$1};
  733.     }
  734.     sub paste_tree
  735.     {
  736.         our @prev;
  737.         our @indent;
  738.         our $env_ref;
  739.         our $env_ref_name;
  740.         my ($parent_ref, $path, $lv) = @_;
  741.         my $adjust;
  742.         if (! defined $env_ref_name)
  743.         {
  744.             wrong("paste_tree", "nothing in memory");
  745.             return;
  746.         }
  747.         $path=~/:([^:]+)$/;        #提取子键
  748.         $parent_ref->{$1}{ $env_ref_name } = $env_ref;
  749.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  750.         $indent[$lv+1] =
  751.             expand($parent_ref, $info[$lv], $path, $indent[$lv]+$adjust);
  752.         
  753.         goto GO_CONTINUE;
  754.     }
  755.     sub append_from_clip
  756.     {
  757.         our @prev;
  758.         our @indent;
  759.         my ($parent_ref, $path, $lv) = @_;
  760.         my $adjust;
  761.         use Win32::Clipboard;
  762.         my $clip = Win32::Clipboard->new();
  763.         $path=~/:([^:]+)$/;        #提取子键
  764.         if ( exists $parent_ref->{$1}{'note'} )
  765.         {
  766.             push @{$parent_ref->{$1}{'note'}},  split(/\r?\n/,$clip->GetText()) ;
  767.         }
  768.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  769.         
  770.         $indent[$lv+1] =
  771.             expand(
  772.                 $parent_ref, $info[$lv], $path, $indent[$lv]+$adjust
  773.             );
  774.         no Win32::Clipboard;
  775.         goto GO_CONTINUE;
  776.     }
  777.     sub edit_notes
  778.     {
  779.         our @prev;
  780.         our @indent;
  781.         my @arr;
  782.         my ($parent_ref, $path, $lv) = @_;
  783.         my $adjust;
  784.         $path=~/:([^:]+)$/;        #提取子键
  785.         if ( exists $parent_ref->{$1}{'note'} )
  786.         {
  787.             use File::Temp 'tempfile';
  788.             my ($fh, $fname) = tempfile();
  789.             print $fh join( "\r\n", @{$parent_ref->{$1}{'note'}} );
  790.             $fh->close();
  791.             no File::Temp;
  792.             system("notepad $fname");
  793.             open READ, "<:raw", $fname or warn "$!";
  794.             @{$parent_ref->{$1}{'note'}} = <READ>;
  795.             for my $i ( @{$parent_ref->{$1}{'note'}} )
  796.             {
  797.                 $i=~s/\r\n$//;
  798.             }
  799.             
  800.             close READ;
  801.         }
  802.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  803.         
  804.         $indent[$lv+1] =
  805.             expand(
  806.                 $parent_ref, $info[$lv], $path, $indent[$lv]+$adjust
  807.             );
  808.         no Win32::Clipboard;
  809.         goto GO_CONTINUE;
  810.     }
  811.     sub ID_to_notes
  812.     {
  813.         our @prev;
  814.         our @indent;
  815.         my @arr;
  816.         my ($parent_ref, $path, $lv) = @_;
  817.         my $adjust;
  818.         $path=~/:([^:]+)$/;        #提取子键
  819.         if ( exists $parent_ref->{$1}{'note'} )
  820.         {
  821.             use File::Temp 'tempfile';
  822.             my ($fh, $fname) = tempfile();
  823.             print $fh join( "\r\n", @{$parent_ref->{$1}{'note'}} ),"\r\n";
  824.             print $fh
  825.             (
  826.                 encode('gbk', " "x4 . " website: \r\n"),
  827.                 encode('gbk', " "x4 . "  E-mail: \r\n"),
  828.                 encode('gbk', " "x4 . "nickname: \r\n"),
  829.                 encode('gbk', " "x4 . "      ID: \r\n"),
  830.                 encode('gbk', " "x4 . "    code: \r\n"),
  831.                 encode('gbk', " "x4 . "   问题1: \r\n"),
  832.                 encode('gbk', " "x4 . "   答案1: \r\n"),
  833.                 encode('gbk', " "x4 . "   问题2: \r\n"),
  834.                 encode('gbk', " "x4 . "   答案2: \r\n"),
  835.                 encode('gbk', " "x4 . "    备注: \r\n"),
  836.                 encode('gbk', " "x4 . "    date: \r\n\r\n"),
  837.             );
  838.             $fh->close();
  839.             no File::Temp;
  840.             system("notepad $fname");
  841.             open READ, "<:raw", $fname or warn "$!";
  842.             @{$parent_ref->{$1}{'note'}} = <READ>;
  843.             for my $i ( @{$parent_ref->{$1}{'note'}} )
  844.             {
  845.                 $i=~s/\r\n$//;
  846.             }
  847.             
  848.             close READ;
  849.         }
  850.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  851.         
  852.         $indent[$lv+1] =
  853.             expand(
  854.                 $parent_ref, $info[$lv], $path, $indent[$lv]+$adjust
  855.             );
  856.         no Win32::Clipboard;
  857.         goto GO_CONTINUE;
  858.     }
  859.     sub BANK_to_notes
  860.     {
  861.         our @prev;
  862.         our @indent;
  863.         my @arr;
  864.         my ($parent_ref, $path, $lv) = @_;
  865.         my $adjust;
  866.         $path=~/:([^:]+)$/;        #提取子键
  867.         if ( exists $parent_ref->{$1}{'note'} )
  868.         {
  869.             use File::Temp 'tempfile';
  870.             my ($fh, $fname) = tempfile();
  871.             print $fh join( "\r\n", @{$parent_ref->{$1}{'note'}} ),"\r\n";
  872.             print $fh
  873.             (
  874.                 encode('gbk', " "x4 . " 开行点: \r\n"),
  875.                 encode('gbk', " "x4 . "   姓名: \r\n"),
  876.                 encode('gbk', " "x4 . "   卡号: \r\n"),
  877.                 encode('gbk', " "x4 . " 登录名: \r\n"),
  878.                 encode('gbk', " "x4 . "passkey: \r\n"),
  879.                 encode('gbk', " "x4 . "   code: \r\n"),
  880.                 encode('gbk', " "x4 . " USBKey: \r\n"),
  881.                 encode('gbk', " "x4 . "   mark: \r\n"),
  882.                 encode('gbk', " "x4 . "   date: \r\n\r\n"),
  883.             );
  884.             $fh->close();
  885.             no File::Temp;
  886.             system("notepad $fname");
  887.             open READ, "<:raw", $fname or warn "$!";
  888.             @{$parent_ref->{$1}{'note'}} = <READ>;
  889.             for my $i ( @{$parent_ref->{$1}{'note'}} )
  890.             {
  891.                 $i=~s/\r\n$//;
  892.             }
  893.             
  894.             close READ;
  895.         }
  896.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  897.         
  898.         $indent[$lv+1] =
  899.             expand(
  900.                 $parent_ref, $info[$lv], $path, $indent[$lv]+$adjust
  901.             );
  902.         no Win32::Clipboard;
  903.         goto GO_CONTINUE;
  904.     }
  905.     sub copy_to_clip
  906.     {
  907.         our @prev;
  908.         our @indent;
  909.         my ($parent_ref, $path, $lv) = @_;
  910.         my $adjust;
  911.         use Win32::Clipboard;
  912.         my $clip = Win32::Clipboard->new();
  913.         $path=~/:([^:]+)$/;        #提取子键
  914.         if ( exists $parent_ref->{$1}{'note'} )
  915.         {
  916.             $clip->Set(
  917.                 join( "\r\n", @{$parent_ref->{$1}{'note'}} )
  918.             );
  919.         }
  920.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  921.         
  922.         $indent[$lv+1] =
  923.             expand(
  924.                 $parent_ref, $info[$lv], $path, $indent[$lv]+$adjust
  925.             );
  926.         no Win32::Clipboard;
  927.         goto GO_CONTINUE;
  928.     }
  929.     sub delete_notes
  930.     {
  931.         our @prev;
  932.         our @indent;
  933.         my ($parent_ref, $path, $lv) = @_;
  934.         my $adjust;
  935.         $path=~/:([^:]+)$/;        #提取子键
  936.         if ( exists $parent_ref->{$1}{'note'} )
  937.         {
  938.             $parent_ref->{$1}{'note'} = [];
  939.         }
  940.         $adjust = ( $lv == 0 ? 0 : $INDENT );
  941.         $indent[$lv+1] =
  942.             expand($parent_ref, $info[$lv], $path, $indent[$lv]+$adjust);
  943.         
  944.         goto GO_CONTINUE;
  945.     }
  946. }
  947. COMMAND: {
  948.     sub lineInput
  949.     {
  950.         our $IN_DEFAULT;
  951.         my $line;
  952.         my $inp;
  953.         my $prompt;
  954.         my $PREV_IN_MODE;
  955.         my $PREV_RECT;
  956.         $line=$MAX_LINE-4;
  957.         $prompt="Command:";
  958.         $PREV_RECT    = $OUT->ReadRect(0, $line-1, $MAX_COL, $line+1);
  959.         $PREV_IN_MODE = $IN->Mode();
  960.         $IN->Mode( $IN_DEFAULT );
  961.         fill_line("-", $MAX_COL, $FG_YELLOW|$BG_CYAN, $line-1);
  962.         fill_line("-", $MAX_COL, $FG_YELLOW|$BG_CYAN, $line+1);
  963.         ClearRect(0, $MAX_COL, $line, $line);
  964.         $OUT->Cursor(0, $line);
  965.         $OUT->Write($prompt);
  966.         $inp=<STDIN>;
  967.         chomp $inp;
  968.         #    如果IN->Mode没有设置为原始状态,<STDIN>将无法退出。
  969.         # $IN句柄在未设置时<STDIN>还是能够通过ENTER键结束行输入的
  970.         # 通过print $IN->Mode(); 得到原始 Mode 代码为183
  971.         #恢复
  972.         $IN->Mode($PREV_IN_MODE);
  973.         $OUT->WriteRect($PREV_RECT, 0, $line-1, $MAX_COL, $line+1);
  974.         return $inp;
  975.     }
  976.     sub linesInput
  977.     {
  978.         our $IN_DEFAULT;
  979.         my $line;
  980.         my $inp;
  981.         my $prompt;
  982.         my $PREV_IN_MODE;
  983.         my $PREV_RECT;
  984.         my @arr;
  985.         $line=$MAX_LINE-4;
  986.         $prompt="INPUT:";
  987.         $PREV_RECT    = $OUT->ReadRect(0, $line-1, $MAX_COL, $line+1);
  988.         $PREV_IN_MODE = $IN->Mode();
  989.         $IN->Mode( $IN_DEFAULT );
  990.         while (1) {
  991.             fill_line("-", $MAX_COL, $FG_YELLOW|$BG_CYAN, $line-1);
  992.             fill_line("-", $MAX_COL, $FG_YELLOW|$BG_CYAN, $line+1);
  993.             ClearRect(0, $MAX_COL, $line, $line);
  994.             $OUT->Cursor(0, $line);
  995.             $OUT->Write($prompt);
  996.             $inp=<STDIN>;
  997.             chomp $inp;
  998.             if (lc($inp) ne "exit") {
  999.                 push(@arr, $inp);
  1000.             } else {
  1001.                 last;
  1002.             }
  1003.         }
  1004.         #    如果IN->Mode没有设置为原始状态,<STDIN>将无法退出。
  1005.         # $IN句柄在未设置时<STDIN>还是能够通过ENTER键结束行输入的
  1006.         # 通过print $IN->Mode(); 得到原始 Mode 代码为183
  1007.         #恢复
  1008.         $IN->Mode($PREV_IN_MODE);
  1009.         $OUT->WriteRect($PREV_RECT, 0, $line-1, $MAX_COL, $line+1);
  1010.         return @arr;
  1011.     }
  1012.     sub inputBar
  1013.     {
  1014.         our $IN_DEFAULT;
  1015.         my $item_ref = shift;
  1016.         my $line;
  1017.         my $inp;
  1018.         my $prompt;
  1019.         my $tmpstr;
  1020.         my $PREV_IN_MODE;
  1021.         my $PREV_RECT;
  1022.         $line = $MAX_LINE - 4;
  1023.         $prompt="Command:";
  1024.         $PREV_RECT    = $OUT->ReadRect(0, $line-1, $MAX_COL, $line+1);
  1025.         $PREV_IN_MODE = $IN->Mode();
  1026.         $IN->Mode( $IN_DEFAULT );
  1027.         while (1)
  1028.         {
  1029.             $OUT->Cls();
  1030.             $tmpstr = join("\n", @{$item_ref->{'note'}} );
  1031.             $OUT->Cursor(0, 1);
  1032.             $OUT->Write( $tmpstr );
  1033.             fill_line("-", $MAX_COL, $FG_YELLOW|$BG_BLACK, $line-1);
  1034.             fill_line("-", $MAX_COL, $FG_YELLOW|$BG_BLACK, $line+1);
  1035.             ClearRect(0, $MAX_COL, $line, $line);  #清理输入的行
  1036.             $OUT->Cursor(0, $line);                #回到行首
  1037.             $OUT->Write( $prompt );
  1038.             $OUT->FillAttr(
  1039.                 $FG_YELLOW|$BG_BLACK,
  1040.                 $MAX_COL,
  1041.                 0,
  1042.                 $line
  1043.             );
  1044.             $inp=<STDIN>;
  1045.             $inp=~s/\r?\n$//;
  1046.             last if (lc($inp) eq "exit");
  1047.             push( @{$item_ref->{'note'}}, $inp );
  1048.         }
  1049.         
  1050.         # MARK_2 待添加功能:命令处理: delete 编号、insert 编号、change 编号
  1051.         #    如果IN->Mode没有设置为原始状态,<STDIN>将无法退出。
  1052.         # $IN句柄在未设置时<STDIN>还是能够通过ENTER键结束行输入的
  1053.         # 通过print $IN->Mode(); 得到原始 Mode 代码为183
  1054.         #恢复
  1055.         $IN->Mode($PREV_IN_MODE);
  1056.         $OUT->WriteRect($PREV_RECT, 0, $line-1, $MAX_COL, $line+1);
  1057.         return $inp;
  1058.     }
  1059.     sub wrong
  1060.     {
  1061.         my ($func_name, $func_say) = @_;
  1062.         $func_say = "Nothing" unless (defined $func_say);
  1063.         $OUT->Cursor(0, 0);
  1064.         $OUT->Write("$func_name say: $func_say");
  1065.         $OUT->FillAttr($FG_YELLOW|$BG_CYAN, $MAX_COL-1, 0, 0);
  1066.     }
  1067. }
  1068. IN_AREA: {
  1069.     sub inRange {
  1070.         my ($a,$x,$b) = @_;
  1071.         if ($a<=$x and $b>=$x) {
  1072.             return 1;
  1073.         } else {
  1074.             return 0;
  1075.         }
  1076.     }
  1077.     sub inRect {
  1078.         my ( $x, $y, $left, $top, $right, $buttom ) = @_;
  1079.         if (   
  1080.                 inRange($left, $x, $right)
  1081.                 and
  1082.                 inRange($top, $y, $buttom)
  1083.             )
  1084.         {
  1085.             return 1;
  1086.         } else {
  1087.             return 0;
  1088.         }
  1089.     }
  1090.     sub inItem {
  1091.         my ( $hash, $mx, $my ) = @_;
  1092.         return 0 if (! defined $$hash{length});
  1093.         if (
  1094.             $$hash{x} <= $mx
  1095.                     and
  1096.             ($$hash{length}+$$hash{x}) >= $mx
  1097.                     and
  1098.             $$hash{y} == $my
  1099.             )
  1100.         {
  1101.             return 1;
  1102.         } else {
  1103.             return 0;
  1104.         }
  1105.         #本函数原来有个BUG,当使用一个空的hash调用的时候,
  1106.         #$hash{x} {y} {length}都为空,但是被作为0计算,当坐标刚好位于0,0 的时候,问题就出来了
  1107.     }
  1108.     sub inDetail {
  1109.         my ( $hash, $mx, $my ) = @_;
  1110.         return 0 if (! defined $$hash{length});
  1111.         # (length-1, length)
  1112.         if (
  1113.             ($$hash{length}+$$hash{x}-1) <= $mx
  1114.                         and
  1115.             $mx < ($$hash{length}+$$hash{x}+1)
  1116.                         and
  1117.             $$hash{y} == $my
  1118.             )
  1119.         {
  1120.             return 1;
  1121.         } else {
  1122.             return 0;
  1123.         }
  1124.     }
  1125. }
  1126. LOAD_SAVE: {
  1127.     sub load_data
  1128.     {
  1129.         my ($hashref, $file) = @_;
  1130.         local $/;
  1131.         $/ = "";
  1132.         my $rf = {};
  1133.         if ( -e $file )
  1134.         {
  1135.             use YAML 'Load';
  1136.             local $YAML::SortKeys;
  1137.             $YAML::SortKeys = 2;
  1138.             open READ,"<:raw:crlf", $file or warn "$!\n";
  1139.             $rf = Load(<READ>);
  1140.             close READ;
  1141.         }
  1142.         if ( (keys %$rf) < 1 )
  1143.         {
  1144.             $rf = {
  1145.                 'Main' => {
  1146.                     'note'=>[],
  1147.                 },
  1148.             };
  1149.         }
  1150.         %$hashref = %$rf;
  1151.     }
  1152.     sub save
  1153.     {
  1154.         use YAML 'Dump';
  1155.         my ($hashref, $file) = @_;
  1156.         local $YAML::Indent;
  1157.         $YAML::Indent = 4;
  1158.         local $YAML::SortKeys;
  1159.         $YAML::SortKeys = 2;
  1160. #        use Data::Dumper;
  1161. #        local  $Data::Dumper::Indent = 2;
  1162. #        open WRT, ">:raw:crlf", "test.txt" or warn "$!";
  1163. #        print WRT Data::Dumper->Dump([$hashref], "['*rcder']");
  1164. #        close WRT;
  1165.         open WRT, ">:raw:crlf", $file or warn "$!";
  1166.         print WRT Dump($hashref);
  1167.         close WRT;
  1168.     }
  1169.     sub logfile
  1170.     {
  1171.         use feature 'state';
  1172.         state $i = 0;
  1173.         my $fname = ".\\log.txt";
  1174.         if ($i == 0) {
  1175.             open WRT,">:raw", $fname or die "$!";
  1176.         } else {
  1177.             open WRT,">>:raw", $fname or die "$!";
  1178.         }
  1179.         print WRT shift;
  1180.         close WRT;
  1181.         $i++;
  1182.     }
  1183. }
  1184. ELSE_FUNCTION: {
  1185.     sub tabformat
  1186.     {
  1187.         my $ref=shift;
  1188.         my @col;
  1189.         my $n;
  1190.         my @tmpr;
  1191.         my @new_array;
  1192.         foreach (@$ref)
  1193.         {
  1194.             @tmpr=split("\t",$_);
  1195.             foreach $n (0..$#tmpr)
  1196.             {
  1197.                 push @col,0 if (! defined $col[$n]);
  1198.                 if ( length($tmpr[$n]) > $col[$n])
  1199.                 {
  1200.                     $col[$n]=length($tmpr[$n]);
  1201.                 }
  1202.             }
  1203.         }
  1204.         my $m=0;
  1205.         foreach (@$ref)
  1206.         {
  1207.             @tmpr=split("\t",$_);
  1208.             foreach $n (0..$#tmpr)
  1209.             {
  1210.                 $new_array[$m].= sprintf("%-${col[$n]}s  ", $tmpr[$n]);
  1211.             }
  1212.             $m++;
  1213.         }
  1214.         return @new_array;
  1215.     }
  1216.     sub get_date
  1217.     {
  1218.         my (
  1219.             $sec, $min, $hour,$mday, $mon, $year,$wday, $yday, $isdst
  1220.         ) = localtime( time() );
  1221.         return sprintf("%d-%02d-%02d", $year+1900, $mon+1, $mday);
  1222.     }
  1223. }
  1224. __END__
  1225.            
复制代码
3

评分人数

强大,路过留名。
http://www.bathome.net/s/tool/index.html

TOP

我也mark一下

TOP

4楼占坑位

TOP

你的Perl脚本不管有没有卵用3楼我先占了再说

TOP

本帖最后由 523066680 于 2015-8-18 18:01 编辑

功能备注:

  • 鼠标移动到某个条目的时候自动展开子条目,移动到条目最右的时候显示该条目下的信息。

  • 支持提取剪切板的信息粘贴到某个子键
    或者复制某个条目下的信息到剪切板(关于剪切板的访问都是在默认输入法为中文的情况下的,否则可能乱码)

  • 可以给条目名称设置编号来决定先后顺序,比如 0_档案, 1_备忘 ,显示的时候编号会被隐藏

  • 复制整个条目,然后在另一个条目粘贴以转移整个条目

TOP

返回列表