# HG changeset patch
# User devi
# Date 1141125086 -7200
# Node ID c70be67ed3d4a87c6afe891785936efb33e0633d
# Parent  3058ada85a582dd01dbaa305c5cf34f76bbc54fa
Наведение порядка в коде.
Обработка чуть лучше отделена от представления.

+ добавлено три совета в документацию

diff -r 3058ada85a58 -r c70be67ed3d4 l3-frontend
--- a/l3-frontend	Sat Feb 25 08:31:35 2006 +0200
+++ b/l3-frontend	Tue Feb 28 13:11:26 2006 +0200
@@ -24,7 +24,7 @@
 # ^^^
 
 our %Stat;
-our %CommandsFDistribution; # Сколько раз в журнале встречается какая команда
+our %frequency_of_command; # Сколько раз в журнале встречается какая команда
 our $table_number=1;
 
 my %mywi_cache_for;         # Кэш для экономии обращений к mywi
@@ -39,6 +39,8 @@
 sub main;
 sub collapse_list($);
 
+sub minutes_passed;
+
 sub print_all;
 sub print_command_lines;
 sub print_files;
@@ -177,7 +179,7 @@
     # Commands
     for my $command (@commands) {
         $command =~ s/'//g;
-        $CommandsFDistribution{$command}++;
+        $frequency_of_command{$command}++;
         if (!$Commands_Description{$command}) {
             $mywi_cache_for{$command} ||= mywi_client ($command) || "";
             my $mywi = join ("\n", grep(/\([18]|sh|script\)/, split(/\n/, $mywi_cache_for{$command})));
@@ -320,6 +322,45 @@
             $$cl->{"class"}.="_root";
         }
 
+#        my $hint;
+#        $hint = make_comment($$cl->{"cline"});
+#        if ($hint) {
+#            $$cl->{hint} = $hint;
+#        }
+        $$cl->{hint}="";
+
+# Выводим <head_lines> верхних строк
+# и <tail_lines> нижних строк,
+# если эти параметры существуют
+        my $output="";
+
+        if ($$cl->{"last_command"} eq "cat" && !$$cl->{"err"} && !($$cl->{"cline"} =~ /</)) {
+            my $filename = $$cl->{"cline"};
+            $filename =~ s/.*\s+(\S+)\s*$/$1/;
+            $Files{$filename}->{"content"} = $$cl->{"output"};
+           $Files{$filename}->{"source_command_id"} = $$cl->{"id"}
+        }
+        my @lines = split '\n', $$cl->{"output"};
+        if ((
+             $Config{"head_lines"} 
+             || $Config{"tail_lines"}
+             )
+             && $#lines >  $Config{"head_lines"} + $Config{"tail_lines"} ) {
+#
+            for (my $i=0; $i<= $#lines && $i < $Config{"head_lines"}; $i++) {
+                $output .= $lines[$i]."\n";
+            }
+            $output .= $Config{"skip_text"}."\n";
+
+            my $start_line=$#lines-$Config{"tail_lines"}+1;
+            for (my $i=$start_line; $i<= $#lines; $i++) {
+                $output .= $lines[$i]."\n";
+            }
+        } 
+        else {
+           $output = $$cl->{"output"};
+        }
+        $$cl->{short_output} = $output;
 
 #Обработка пометок
 #  Если несколько пометок (notes) идут подряд, 
@@ -379,6 +420,13 @@
                 $$cl=0;
             }
         }
+        if ($$cl->{"class"} == "note") {
+                my $note_html = $$cl->{note};
+                $note_html = join ("\n", map ("<p>$_</p>", split (/-\n/, $note)));
+                $note_html =~ s@(http:[a-zA-Z.0-9/?\_%-]*)@<a href='$1'>$1</a>@g;
+                $note_html =~ s@(www\.[a-zA-Z.0-9/?\_%-]*)@<a href='$1'>$1</a>@g;
+                $$cl->{"note_html"} = $note_html;
+        }
     }   
 
 }
@@ -420,8 +468,6 @@
         }
     }
 
-    #$result = "Filter=".$Config{filter}."\n";
-
     $Stat{LastCommand}   ||= 0;
     $Stat{TotalCommands} ||= 0;
     $Stat{ErrorCommands} ||= 0;
@@ -451,11 +497,7 @@
 # Если у нас недостаточно информации о том, подходит строка под  фильтр или нет, 
 # мы её выводим
 
-        #$result .= "before<br/>";
         for my $filter_key (keys %filter) {
-            #$result .= "undefined local session id<br/>\n" if !defined($cl->{local_session_id});
-            #$result .= "undefined filter key $filter_key <br/>\n" if !defined($Sessions{$cl->{local_session_id}}->{$filter_key});
-            #$result .= $Sessions{$cl->{local_session_id}}->{$filter_key}." != ".$filter{$filter_key};
             next COMMAND_LINE 
                 if defined($cl->{local_session_id})
                 && defined($Sessions{$cl->{local_session_id}}->{$filter_key})
@@ -470,10 +512,13 @@
             $Stat{TotalTime} += $cl->{time} - $Stat{LastCommand}
         }
         my $seconds_since_last_command = $cl->{time} - $Stat{LastCommand};
+
+        if ($Stat{LastCommand} > $cl->{time}) {
+               $result .= "Время идёт вспять<br/>";
+        };
         $Stat{LastCommand} = $cl->{time};
         $Stat{TotalCommands}++;
 
-
 # Пропускаем строки, выходящие за границу "signature",
 # при условии, что границы указаны
 # Пропускаем неправильные/прерванные/другие команды
@@ -490,14 +535,22 @@
                 || ($Config{"skip_wrong"} =~ /^y/i     && $cl->{"err"} != 0)
                 || ($Config{"skip_interrupted"} =~ /^y/i && $cl->{"err"} == 130);
         
+
+
+
+#
+##
+## Начинается собственно вывод
+##
+#
+
+### Сначала обрабатываем границы разделов
+### Если тип команды "note", это граница
+
         if ($cl->{class} eq "note") {
-            my $note = $cl->{note};
-            $note = join ("\n", map ("<p>$_</p>", split (/-\n/, $note)));
-            $note =~ s@(http:[a-zA-Z.0-9/?\_%-]*)@<a href='$1'>$1</a>@g;
-            $note =~ s@(www\.[a-zA-Z.0-9/?\_%-]*)@<a href='$1'>$1</a>@g;
             $this_day_result .= "<tr><td colspan='6'>"
                              .  "<h4 id='note$note_number'>".$cl->{note_title}."</h4>" if $cl->{note_title}
-                             .  "".$note."<p/><p/></td></tr>";
+                             .  "".$cl->{note_html}."<p/><p/></td></tr>";
 
             if ($cl->{note_title}) {
                 push @{$toc[@toc]},"<a href='#note$note_number'>".$cl->{note_title}."</a>";
@@ -506,45 +559,6 @@
             next;
         }
 
-
-        my $output="";
-# Выводим <head_lines> верхних строк
-# и <tail_lines> нижних строк,
-# если эти параметры существуют
-
-        if ($cl->{"last_command"} eq "cat" && !$cl->{"err"} && !($cl->{"cline"} =~ /</)) {
-            my $filename = $cl->{"cline"};
-            $filename =~ s/.*\s+(\S+)\s*$/$1/;
-            $Files{$filename}->{"content"} = $cl->{"output"};
-            $Files{$filename}->{"source_command_id"} = $cl->{"id"}
-        }
-        my @lines = split '\n', $cl->{"output"};
-        if ((
-             $Config{"head_lines"} 
-             || $Config{"tail_lines"}
-             )
-             && $#lines >  $Config{"head_lines"} + $Config{"tail_lines"} ) {
-
-            for (my $i=0; $i<= $#lines && $i < $Config{"head_lines"}; $i++) {
-                $output .= $lines[$i]."\n";
-            }
-            $output .= $Config{"skip_text"}."\n";
-
-            my $start_line=$#lines-$Config{"tail_lines"}+1;
-            for ($i=$start_line; $i<= $#lines; $i++) {
-                $output .= $lines[$i]."\n";
-            }
-        } 
-        else {
-           $ output .= $cl->{"output"};
-        }   
-
-#
-##
-## Начинается собственно вывод
-##
-#
-
         my ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = localtime($cl->{time});
 
         # Добавляем спереди 0 для удобочитаемости
@@ -555,47 +569,27 @@
         $class=$cl->{"class"};
         $Stat{ErrorCommands}++          if $class =~ /wrong/;
         $Stat{MistypedCommands}++       if $class =~ /mistype/;
-        
-        
+
 # DAY CHANGE
         if ( $last_day ne $day) {
             if ($last_day) {
 
 # Вычисляем разность множеств.
 # Что-то вроде этого, если бы так можно было писать:
-#   @new_commands = keys %CommandsFDistribution - @known_commands;
+#   @new_commands = keys %frequency_of_command - @known_commands;
 
 
                 $result .= "<h3 id='day$last_day'>".$Day_Name[$last_wday]."</h3>";
-
-
-
                 for my $entry_class (sort keys %new_entries_of) {
-                    my $new_commands_section = make_new_entries_table($entry_class=~/[0-9]+\s+(.*)/, \@known_commands);
-
-                    my $table_caption = "Таблица "
-                                      . $table_number++
-                                      . ". "
-                                      . $Day_Name[$last_wday]
-                                      . ". Новые "
-                                      . $new_entries_of{$entry_class};
-                    if ($new_commands_section) {
-                        $result .= "<table class='new_commands_table' width='700' cellspacing='0' cellpadding='0'>"
-                                .  "<tr class='new_commands_caption'>"
-                                .  "<td colspan='2' align='right'>$table_caption</td>"
-                                .  "</tr>"
-                                .  "<tr class='new_commands_header'>"
-                                .  "<td width=100>Команда</td><td width=600>Описание</td>"
-                                .  "</tr>"
-                                .  $new_commands_section 
-                                .  "</table>"
-                    }
-
+                    my $table_caption = "Таблица ".$table_number++.".".$Day_Name[$last_wday]
+                                        .". Новые ".$new_entries_of{$entry_class};
+                    my $new_commands_section = make_new_entries_table(
+                                                $table_caption, 
+                                                $entry_class=~/[0-9]+\s+(.*)/, 
+                                                \@known_commands);
                 }
-                @known_commands = keys %CommandsFDistribution;
-                #$result .= "<table width='100%'>\n";
+                @known_commands = keys %frequency_of_command;
                 $result .= $this_day_result;
-                #$result .= "</table>";
             }
 
             push @toc, "<a href='#day$day'>".$Day_Name[$wday]."</a>\n";
@@ -603,47 +597,11 @@
             $last_wday=$wday;
             $this_day_result = q();
         }
-        elsif ($seconds_since_last_command > 7200) {
-            my $hours_passed =  int($seconds_since_last_command/3600);
-            my $passed_word  = $hours_passed % 10 == 1 ? "прошла"
-                                                         : "прошло";
-            my $hours_word   = $hours_passed % 10 == 1 ?   "часа":
-                                                           "часов";
-            $this_day_result .= "<div class='much_time_passed'>"
-                             .  $passed_word." &gt;".$hours_passed." ".$hours_word
-                             .  "</div>\n";
-        }
-        elsif ($seconds_since_last_command > 600) {
-            my $minutes_passed =  int($seconds_since_last_command/60);
-
-
-            my $passed_word  = $minutes_passed % 100 > 10 
-                            && $minutes_passed % 100 < 20 ? "прошло"
-                             : $minutes_passed % 10 == 1  ? "прошла"
-                                                          : "прошло";
-
-            my $minutes_word = $minutes_passed % 100 > 10 
-                            && $minutes_passed % 100 < 20 ? "минут" :
-                               $minutes_passed % 10 == 1 ? "минута":
-                               $minutes_passed % 10 == 0 ? "минут" :
-                               $minutes_passed % 10  > 4 ? "минут" :
-                                                           "минуты";
-
-            if ($seconds_since_last_command < 1800) {
-            $this_day_result .= "<div class='time_passed'>"
-                             .  $passed_word." ".$minutes_passed." ".$minutes_word
-                             .  "</div>\n";
-            }
-            else {
-            $this_day_result .= "<div class='much_time_passed'>"
-                             .  $passed_word." ".$minutes_passed." ".$minutes_word
-                             .  "</div>\n";
-            }
+        else {
+            $this_day_result .= minutes_passed($seconds_since_last_command);
         }
 
-        #$this_day_result .= "<table cellspacing='0' cellpading='0' class='command' id='command:".$cl->{"id"}."' width='100%'><tr>\n";
         $this_day_result .= "<div class='command' id='command:".$cl->{"id"}."' >\n";
-                        
 
 # CONSOLE CHANGE
         if ($cl->{"tty"} && $last_tty ne $cl->{"tty"} && 0) {
@@ -657,44 +615,29 @@
 # Session change
         if ( $last_session ne $cl->{"local_session_id"}) {
             my $tty = $cl->{"tty"};
-            $this_day_result .= "<a href='?local_session_id=".$cl->{"local_session_id"}."'><div class='ttychange'>"
+            $this_day_result .= "<div class='ttychange'><a href='?local_session_id=".$cl->{"local_session_id"}."'>"
                                 . $Sessions{$cl->{"local_session_id"}}->{"tty"}
-                                ."</div></a>";
+                                ."</a></div>";
             $last_session=$cl->{"local_session_id"};
         }
 
 # TIME
-        $this_day_result .= "<div class='time'>$hour:$min:$sec</div>" 
-                            if $Config{"show_time"} =~ /^y/i;
-
-        #$this_day_result .= $Config{"show_time"} =~ /^y/i
-        #         ? "<td width='100' valign='top' class='time' width='$Config{time_width}'>$hour:$min:$sec</td>"
-        #         : "<td width='0'/>";
-
-# CLASS
-#        if ($cl->{"err"}) {
-#            $this_day_result .= "<td width='6' valign='top'>"
-#                             .  "<table><tr><td width='6' height='6' class='err_box'>"
-#                             .  "E"
-#                             .  "</td></tr></table>"
-#                             .  "</td>";
-#        }
-#        else {
-#            $this_day_result .= "<td width='10' valign='top'>"
-#                             .  " "
-#                             .  "</td>";
-#        }
+        if ($Config{"show_time"} =~ /^y/i) {
+            $this_day_result .= "<div class='time'>$hour:$min:$sec</div>" 
+        }
 
 # COMMAND
-        my $hint = make_comment($cl->{"cline"});
-
         my $cline;
         $prompt_hint = join ("&#10;", map("$_=$cl->{$_}", grep (!/^(output|diff)$/, sort(keys(%{$cl})))));
         $cline = "<span title='$prompt_hint'>".$cl->{"prompt"}."</span>".$cl->{"cline"};
         $cline =~ s/\n//;
 
-        $cline = "<span title='$hint' class='with_hint'>$cline</span>" if $hint;
-        $cline = "<span class='without_hint'>$cline</span>" if !$hint;
+        if ($cl->{"hint"}) {
+            $cline = "<span title='$cl->{hint}' class='with_hint'>$cline</span>" ;
+        } 
+        else {
+            $cline = "<span class='without_hint'>$cline</span>";
+        }
 
         $this_day_result .= "<table cellpadding='0' cellspacing='0'><tr><td>\n<div class='cblock_$cl->{class}'>\n";
         $this_day_result .= "<div class='cline'>\n" . $cline ;      #cline
@@ -710,8 +653,8 @@
         $Config{"suppress_pagers"}  =~ /^y/i && grep ($_ eq $last_command, @{$Config{"pagers"}}) ||
         $Config{"suppress_terminal"}=~ /^y/i && grep ($_ eq $last_command, @{$Config{"terminal"}})
             )) {
-            $this_day_result .= "<pre class='output'>\n" . $output . "</pre>\n";
-        }   
+            $this_day_result .= "<pre class='output'>\n" . $cl->{short_output} . "</pre>\n";
+        }
 
 # DIFF
         $this_day_result .= "<pre class='diff'>".$cl->{"diff"}."</pre>"
@@ -738,19 +681,6 @@
             $this_day_result .= "</div>\n";
         }
 
-# COMMENT
-        if ( $Config{"show_comments"} =~ /^y/i) {
-            my $comment = make_comment($cl->{"cline"});
-            if ($comment) {
-                $this_day_result .= 
-                           "<div class='note' width='100%'>"
-                        .  $comment
-                        .  "</div>\n"
-                        ;
-                 
-            }
-        }
-
         # Вывод очередной команды окончен
         $this_day_result .= "</div>\n";                     # cblock
         $this_day_result .= "</td></tr></table>\n"
@@ -760,28 +690,14 @@
         $result .= "<h3 id='day$last_day'>".$Day_Name[$last_wday]."</h3>";
 
         for my $entry_class (keys %new_entries_of) {
-            my $new_commands_section = make_new_entries_table($entry_class=~/[0-9]+\s+(.*)/, \@known_commands);
-            my $table_caption = "Таблица "
-                                . $table_number++
-                                . ". "
-                                . $Day_Name[$last_wday]
-                                . ". Новые "
-                                . $new_entries_of{$entry_class};
-            if ($new_commands_section) {
-                $result .= "<table class='new_commands_table' width='700' cellspacing='0' cellpadding='0'>"
-                        .  "<tr class='new_commands_caption'>"
-                        .  "<td colspan='2' align='right'>$table_caption</td>"
-                        .  "</tr>"
-                        .  "<tr class='new_commands_header'>"
-                        .  "<td width=100>Команда</td><td width=600>Описание</td>"
-                        .  "</tr>"
-                        .  $new_commands_section 
-                        .  "</table>"
-            }
-
+            my $table_caption = "Таблица ".$table_number++.".".$Day_Name[$last_wday]
+                              . ". Новые ".$new_entries_of{$entry_class};
+            my $new_commands_section = make_new_entries_table(
+                                        $table_caption, 
+                                        $entry_class=~/[0-9]+\s+(.*)/, 
+                                        \@known_commands);
         }
-        @known_commands = keys %CommandsFDistribution;
-
+        @known_commands = keys %frequency_of_command;
         $result .= $this_day_result;
    }
 
@@ -789,25 +705,36 @@
 
 }
 
+#############
+# print_all
+#
+# Напечатать таблицу неизвестных команд
+#
+# In:       $_[0]       table_caption
+#           $_[1]       entries_class
+#           @_[2..]     known_commands
+# Out:
+
 sub make_new_entries_table
 {
+    my $table_caption;
     my $entries_class = shift;
     my @known_commands = @{$_[0]};
+    my $result = "";
 
     my %count;
     my @new_commands = ();
-    for my $c (keys %CommandsFDistribution, @known_commands) {
+    for my $c (keys %frequency_of_command, @known_commands) {
         $count{$c}++
     }
-    for my $c (keys %CommandsFDistribution) {
+    for my $c (keys %frequency_of_command) {
         push @new_commands, $c if $count{$c} != 2;
     }
 
-    
     my $new_commands_section;
     if (@new_commands){
         my $hint;
-        for my $c (reverse sort { $CommandsFDistribution{$a} <=> $CommandsFDistribution{$b} } @new_commands) {
+        for my $c (reverse sort { $frequency_of_command{$a} <=> $frequency_of_command{$b} } @new_commands) {
                 $hint = make_comment($c);
                 next unless $hint;
                 my ($command, $hint) = $hint =~ m/(.*?) \s*- \s*(.*)/;
@@ -815,9 +742,71 @@
                 $new_commands_section .= "<tr><td valign='top'>$command</td><td>$hint</td></tr>";
         }
     }
-    return $new_commands_section;
+    if ($new_commands_section) {
+        $result .= "<table class='new_commands_table' width='700' cellspacing='0' cellpadding='0'>"
+                .  "<tr class='new_commands_caption'>"
+                .  "<td colspan='2' align='right'>$table_caption</td>"
+                .  "</tr>"
+                .  "<tr class='new_commands_header'>"
+                .  "<td width=100>Команда</td><td width=600>Описание</td>"
+                .  "</tr>"
+                .  $new_commands_section 
+                .  "</table>"
+    }
+    return $result;
 }
 
+#############
+# print_all
+#
+#
+#
+# In:       $_[0]       seconds_since_last_command
+# Out:                  "minutes passed" text
+
+sub minutes_passed
+{
+        my $seconds_since_last_command = shift;
+        my $result = "";
+        if ($seconds_since_last_command > 7200) {
+            my $hours_passed =  int($seconds_since_last_command/3600);
+            my $passed_word  = $hours_passed % 10 == 1 ? "прошла"
+                                                         : "прошло";
+            my $hours_word   = $hours_passed % 10 == 1 ?   "часа":
+                                                           "часов";
+            $result .= "<div class='much_time_passed'>"
+                    .  $passed_word." &gt;".$hours_passed." ".$hours_word
+                    .  "</div>\n";
+        }
+        elsif ($seconds_since_last_command > 600) {
+            my $minutes_passed =  int($seconds_since_last_command/60);
+
+
+            my $passed_word  = $minutes_passed % 100 > 10 
+                            && $minutes_passed % 100 < 20 ? "прошло"
+                             : $minutes_passed % 10 == 1  ? "прошла"
+                                                          : "прошло";
+
+            my $minutes_word = $minutes_passed % 100 > 10 
+                            && $minutes_passed % 100 < 20 ? "минут" :
+                               $minutes_passed % 10 == 1 ? "минута":
+                               $minutes_passed % 10 == 0 ? "минут" :
+                               $minutes_passed % 10  > 4 ? "минут" :
+                                                           "минуты";
+
+            if ($seconds_since_last_command < 1800) {
+                $result .= "<div class='time_passed'>"
+                        .  $passed_word." ".$minutes_passed." ".$minutes_word
+                        .  "</div>\n";
+            }
+            else {
+                $result .= "<div class='much_time_passed'>"
+                        .  $passed_word." ".$minutes_passed." ".$minutes_word
+                        .  "</div>\n";
+            }
+        }
+        return $result;
+}
 
 #############
 # print_all
@@ -1041,7 +1030,7 @@
     # Некоторые значения пересчитываются!
     # Дальше их лучше уже не использовать!!!
 
-    my %CommandsFrequency = %CommandsFDistribution;
+    my %CommandsFrequency = %frequency_of_command;
 
     $Stat{TotalTime} ||= 0;
     my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($Stat{FirstCommand} || 0);
@@ -1362,6 +1351,41 @@
     добавляются точно таким же способом, только вместо симолов #^ или #v 
     нужно использовать символы #=
     </p></li>
+
+    <p><li>
+    Содержимое файла может быть показано в журнале.
+    Для этого его нужно вывести с помощью программы cat.
+    Если вывод команды отметить симоволами #!, 
+    содержимое файла будет показано в журнале
+    в специально отведённой для этого секции.
+    </li></p>
+
+    <p>
+    <li>
+    Для того чтобы вставить скриншот интересующего вас окна в журнал,
+    нужно воспользоваться командой l3shot.
+    После того как команда вызвана, нужно с помощью мыши выбрать окно, которое
+    должно быть в журнале.
+    </li>
+    </p>
+
+    <p>
+    <li>
+    Команды в журнале расположены в хронологическом порядке.
+    Если две команды давались одна за другой, но на разных терминалах,
+    в журнале они будут рядом, даже если они не имеют друг к другу никакого отношения.
+<pre>
+1
+    2
+3   
+    4
+</pre>
+    Группы команд, выполненных на разных терминалах, разделяются специальной линией.
+    Под этой линией в правом углу показано имя терминала, на котором выполнялись команды.
+    Для того чтобы посмотреть команды только одного сенса, 
+    нужно щёкнуть по этому названию.
+    </li>
+    </p>
 </ol>
 HELP