# HG changeset patch
# User devi
# Date 1135724460 -7200
# Node ID 43aeb3036aaa0a3f35edad44a800683cc8028db1
# Parent d3fcff5e375752452dbd32d18fce39275c4b6600
l3-frontend:
Наведение порядка в коде. Пока что, он ещё достаточно сырой
и некрасивый, но это всё же лучше, чем то, что было раньше.
Добавлено:
* команды, набранные с ошибками показываются зачёркнутым текстом
* в статистике подсвечиваются известные/неизвестные команды,
как раньше по тексту
* в названиях программ/скриптов пути, содержащие /etc, не отрезаются
l3-agent:
Неправильно передавался код завершения. Fixed
Код откровенно мерзкий и требует доработок
diff -r d3fcff5e3757 -r 43aeb3036aaa l3-agent
--- a/l3-agent Thu Dec 22 11:56:06 2005 +0200
+++ b/l3-agent Wed Dec 28 01:01:00 2005 +0200
@@ -814,7 +814,7 @@
print OUT "",$cl->{raw_file},"\n";
print OUT "",$cl->{tty},"\n";
print OUT "",$out_class,"\n";
- print OUT "",$out_class,"\n";
+ print OUT "",$cl->{err},"\n";
print OUT "";
printq(\*OUT,,$cl->{"prompt"});
print OUT "";
diff -r d3fcff5e3757 -r 43aeb3036aaa l3-frontend
--- a/l3-frontend Thu Dec 22 11:56:06 2005 +0200
+++ b/l3-frontend Wed Dec 28 01:01:00 2005 +0200
@@ -25,18 +25,21 @@
my %mywi_cache_for; # Кэш для экономии обращений к mywi
-
-sub search_buy;
sub make_comment;
sub load_command_lines_from_xml;
sub load_sessions_from_xml;
-sub print_command_lines;
sub sort_command_lines;
sub process_command_lines;
sub init_variables;
sub main;
sub collapse_list($);
+sub print_all;
+sub print_command_lines;
+sub print_stat;
+sub print_header;
+sub print_footer;
+
main();
sub main
@@ -51,71 +54,75 @@
load_sessions_from_xml($Config{"backend_datafile"});
sort_command_lines;
process_command_lines;
- print_command_lines($Config{"output"});
+ print_all($Config{"output"});
close_mywi_socket;
}
+# extract_from_cline
-sub search_by
-{
- my $sm = shift;
- my $topic = shift;
- $topic =~ s/ /+/;
-
- return "";
-}
+# In: $what = commands | args
+# Out: return ссылка на хэш, содержащий результаты разбора
+# команда => позиция
-sub extract_from_cline
# Разобрать командную строку $_[1] и возвратить хэш, содержащий
# номер первого появление команды в строке:
# команда => первая позиция
+sub extract_from_cline
{
my $what = $_[0];
my $cline = $_[1];
my @lists = split /\;/, $cline;
- my @commands = ();
- for my $list (@lists) {
- push @commands, split /\|/, $list;
+ my @command_lines = ();
+ for my $command_list (@lists) {
+ push(@command_lines, split(/\|/, $command_list));
}
- my %commands;
- my %args;
+ my %position_of_command;
+ my %position_of_arg;
my $i=0;
- for my $command (@commands) {
- $command =~ s@^\s*\S+/@@;
- $command =~ /\s*(\S+)\s*(.*)/;
+ for my $command_line (@command_lines) {
+ $command_line =~ s@^\s*@@;
+ $command_line =~ /\s*(\S+)\s*(.*)/;
if ($1 && $1 eq "sudo" ) {
- $commands{"$1"}=$i++;
- $command =~ s/\s*sudo\s+//;
+ $position_of_command{"$1"}=$i++;
+ $command_line =~ s/\s*sudo\s+//;
}
- $command =~ s@^\s*\S+/@@;
- $command =~ /\s*(\S+)\s*(.*)/;
- if ($1 && !defined $commands{"$1"}) {
- $commands{"$1"}=$i++;
+ if ($command_line !~ m@^\s*\S*/etc/@) {
+ $command_line =~ s@^\s*\S+/@@;
+ }
+
+ $command_line =~ /\s*(\S+)\s*(.*)/;
+ my $command = $1;
+ my $args = $2;
+ if ($command && !defined $position_of_command{"$command"}) {
+ $position_of_command{"$command"}=$i++;
};
- if ($2) {
- my $args = $2;
+ if ($args) {
my @args = split (/\s+/, $args);
for my $a (@args) {
- $args{"$a"}=$i++
- if !defined $args{"$a"};
+ $position_of_arg{"$a"}=$i++
+ if !defined $position_of_arg{"$a"};
};
-
-
}
}
if ($what eq "commands") {
- return \%commands;
+ return \%position_of_command;
} else {
- return \%args;
+ return \%position_of_arg;
}
}
+
+
+
+#
+# Подпрограммы для работы с mywi
+#
+
sub open_mywi_socket
{
$Mywi_Socket = IO::Socket::INET->new(
@@ -204,6 +211,9 @@
Процедура load_command_lines_from_xml выполняет загрузку разобранного lab-скрипта
из XML-документа в переменную @Command_Lines
+# In: $datafile имя файла
+# Out: @CommandLines загруженные командные строки
+
Предупреждение!
Процедура не в состоянии обрабатывать XML-документ любой структуры.
В действительности файл cache из которого загружаются данные
@@ -248,11 +258,12 @@
}
+# sort_command_lines
+# In: @Command_Lines
+# Out: @Command_Lies_Index
sub sort_command_lines
{
- # Sort Command_Lines
- # Write Command_Lines to Command_Lines_Index
my @index;
for (my $i=0;$i<=$#Command_Lines;$i++) {
@@ -265,99 +276,87 @@
}
+##################
+# process_command_lines
+#
+# Обрабатываются командные строки @Command_Lines
+# Для каждой строки определяется:
+# class класс
+# note комментарий
+#
+# In: @Command_Lines_Index
+# In-Out: @Command_Lines
+
sub process_command_lines
{
for my $i (@Command_Lines_Index) {
+ my $cl = \$Command_Lines[$i];
- my $cl = \$Command_Lines[$i];
- #@{${$cl}->{"new_commands"}} =();
- #@{${$cl}->{"new_files"}} =();
- $$cl->{"class"} = "";
+ next if !$cl;
- if ($$cl->{"err"}) {
- $$cl->{"class"}="wrong";
- $$cl->{"class"}="interrupted"
- if ($$cl->{"err"} eq 130);
- }
+ $$cl->{err} ||=0;
+
+ # Класс команды
+
+ $$cl->{"class"} = $$cl->{"err"} eq 130 ? "interrupted"
+ : $$cl->{"err"} eq 127 ? "mistyped"
+ : $$cl->{"err"} ? "wrong"
+ : "";
+
if (!$$cl->{"euid"}) {
$$cl->{"class"}.="_root";
}
-
-#tab# my @tab_words=split /\s+/, $$cl->{"output"};
-#tab# my $last_word= $$cl->{"cline"} =~ /(\S*)$/;
-#tab# $last_word =~ s@.*/@@;
-#tab# my $this_is_tab=1;
-#tab#
-#tab# if ($last_word && @tab_words >2) {
-#tab# for my $tab_words (@tab_words) {
-#tab# if ($tab_words !~ /^$last_word/) {
-#tab# $this_is_tab=0;
-#tab# last;
-#tab# }
-#tab# }
-#tab# }
-#tab# $$cl->{"class"}="tab" if $this_is_tab;
-
-# if ( !$$cl->{"err"}) {
-# # Command does not contain mistakes
-#
-# my %commands = extract_from_cline("commands", ${$cl}->{"cline"});
-# my %files = extract_from_cline("files", ${$cl}->{"cline"});
-#
-# # Searching for new commands only
-# for my $command (keys %commands) {
-# if (!defined $Commands_Stat{$command}) {
-# push @{$$cl->{new_commands}}, $command;
-# }
-# $Commands_Stat{$command}++;
-# }
-#
-# for my $file (keys %files) {
-# if (!defined $Files_Stat{$file}) {
-# push @{$$cl->{new_files}}, $file;
-# }
-# $Files_Stat{$file}++;
-# }
-# }
+
+#Обработка пометок
+# Если несколько пометок (notes) идут подряд,
+# они все объединяются
if ($$cl->{cline}=~ m@cat[^#]*#([\^=v])\s*(.*)@) {
- if ($1 eq "=") {
+
+ my $note_operator = $1;
+ my $note_title = $2;
+
+ if ($note_operator eq "=") {
$$cl->{"class"} = "note";
$$cl->{"note"} = $$cl->{"output"};
$$cl->{"note_title"} = $2;
}
else {
my $j = $i;
- if ($1 eq "^") {
+ if ($note_operator eq "^") {
$j--;
$j-- while ($j >=0 && (!$Command_Lines[$j] || $Command_Lines[$j]->{tty} ne $$cl->{tty}));
}
- elsif ($1 eq "v") {
+ elsif ($note_operator eq "v") {
$j++;
$j++ while ($j <= @Command_Lines && (!$Command_Lines[$j] || $Command_Lines[$j]->{tty} ne $$cl->{tty}));
}
- $Command_Lines[$j]->{note_title}="$2";
- $Command_Lines[$j]->{note}=$$cl->{output};
+ $Command_Lines[$j]->{note_title}=$note_title;
+ $Command_Lines[$j]->{note}.=$$cl->{output};
$$cl=0;
}
}
elsif ($$cl->{cline}=~ /#([\^=v])(.*)/) {
- if ($1 eq "=") {
+
+ my $note_operator = $1;
+ my $note_text = $2;
+
+ if ($note_operator eq "=") {
$$cl->{"class"} = "note";
- $$cl->{"note"} = $2;
+ $$cl->{"note"} = $note_text;
}
else {
my $j=$i;
- if ($1 eq "^") {
+ if ($note_operator eq "^") {
$j--;
$j-- while ($j >=0 && (!$Command_Lines[$j] || $Command_Lines[$j]->{tty} ne $$cl->{tty}));
}
- elsif ($1 eq "v") {
+ elsif ($note_operator eq "v") {
$j++;
$j++ while ($j <= @Command_Lines && $Command_Lines[$j]->{tty} ne $$cl->{tty} || !$Command_Lines[$j]);
}
- $Command_Lines[$j]->{note}.="$2\n";
+ $Command_Lines[$j]->{note}.="$note_text\n";
$$cl=0;
}
}
@@ -375,64 +374,74 @@
sub print_command_lines
{
- my $output_filename=$_[0];
- my $course_name = $Config{"course-name"};
- my $course_code = $Config{"course-code"};
- my $course_date = $Config{"course-date"};
- my $course_center = $Config{"course-center"};
- my $course_trainer = $Config{"course-trainer"};
- my $course_student = $Config{"course-student"};
-
-
- # Результат выполнения процедуры равен
- # join("", @Result{header,body,stat,help,about,footer})
- my %Result;
- my @toc; # Хранит оглавление
+ my @toc; # Оглавление
my $note_number=0;
- $Result{"body"} = "
\n";
+ my $result = q();
+ my $this_day_resut = q();
my $cl;
my $last_tty="";
- my $last_day="";
+ my $last_day=q();
+ my $last_wday=q();
my $in_range=0;
my $current_command=0;
+ my %filter;
+
+ if ($Config{filter}) {
+ # Инициализация фильтра
+ my %filter;
+ for (split /&/,$Config{filter}) {
+ my ($var, $val) = split /=/;
+ $filter{$var} = $val || "";
+ }
+ }
+
+ $Stat{LastCommand} ||= 0;
+ $Stat{TotalCommands} ||= 0;
+ $Stat{ErrorCommands} ||= 0;
+ $Stat{MistypedCommands} ||= 0;
+
COMMAND_LINE:
for my $k (@Command_Lines_Index) {
my $cl=$Command_Lines[$Command_Lines_Index[$current_command++]];
-
next unless $cl;
+# Пропускаем команды, с одинаковым временем
+# Это не совсем правильно.
+# Возможно, что это команды, набираемые с помощью
+# или запомненные с помощью
- if ($Config{filter}) {
- # Инициализация фильтра
- my %filter;
- for (split /&/,$Config{filter}) {
- my ($var, $val) = split /=/;
- $filter{$var} = $val || "";
- }
+ next if $Stat{LastCommand} == $cl->{time};
- for my $filter_key (keys %filter) {
- next COMMAND_LINE if
- defined($cl->{local_session_id})
- && defined($Sessions{$cl->{local_session_id}}->{$filter_key})
- && $Sessions{$cl->{local_session_id}}->{$filter_key} ne $filter{$filter_key};
- #print $filter_key,"\n";
- }
+# Набираем статистику
+# Хэш %Stat
- #if ($filter{user}) {
- # next COMMAND_LINE unless $Sessions{$cl->{local_session_id}}->{user} eq $filter{user};
- #}
+ $Stat{FirstCommand} = $cl->{time} unless $Stat{FirstCommand};
+ if ($cl->{time} - $Stat{LastCommand} < $Config{stat_inactivity_interval}) {
+ $Stat{TotalTime} += $cl->{time} - $Stat{LastCommand}
+ }
+ $Stat{LastCommand} = $cl->{time};
+ $Stat{TotalCommands}++;
- #for my $filter_field (keys %filter) {
- # next COMMAND_LINE unless $Sessions{$cl->{local_session_id}}->{$filter_field} eq $filter{$filter_field};
- #}
+# Пропускаем строки, которые противоречат фильтру
+# Если у нас недостаточно информации о том, подходит строка под фильтр или нет,
+# мы её выводим
+
+ for my $filter_key (keys %filter) {
+ next COMMAND_LINE if
+ defined($cl->{local_session_id})
+ && defined($Sessions{$cl->{local_session_id}}->{$filter_key})
+ && $Sessions{$cl->{local_session_id}}->{$filter_key} ne $filter{$filter_key};
}
+# Пропускаем строки, выходящие за границу "signature",
+# при условии, что границы указаны
+# Пропускаем неправильные/прерванные/другие команды
if ($Config{"from"} && $cl->{"cline"} =~ /$Config{"signature"}\s*$Config{"from"}/) {
$in_range=1;
next;
@@ -441,25 +450,19 @@
$in_range=0;
next;
}
- next if ($Config{"from"} && $Config{"to"} && !$in_range)
- ||
- ($Config{"skip_empty"} =~ /^y/i && $cl->{"cline"} =~ /^\s*$/ )
- ||
- ($Config{"skip_wrong"} =~ /^y/i && $cl->{"err"} != 0)
- ||
- ($Config{"skip_interrupted"} =~ /^y/i && $cl->{"err"} == 130);
+ next if ($Config{"from"} && $Config{"to"} && !$in_range)
+ || ($Config{"skip_empty"} =~ /^y/i && $cl->{"cline"} =~ /^\s*$/ )
+ || ($Config{"skip_wrong"} =~ /^y/i && $cl->{"err"} != 0)
+ || ($Config{"skip_interrupted"} =~ /^y/i && $cl->{"err"} == 130);
- #my @new_commands=@{$cl->{"new_commands"}};
- #my @new_files=@{$cl->{"new_files"}};
-
if ($cl->{class} eq "note") {
my $note = $cl->{note};
$note = join ("\n", map ("$_
", split (/-\n/, $note)));
$note =~ s@(http:[a-zA-Z.0-9/?\_%-]*)@$1@g;
$note =~ s@(www\.[a-zA-Z.0-9/?\_%-]*)@$1@g;
- $Result{"body"} .= "";
- $Result{"body"} .= "".$cl->{note_title}."" if $cl->{note_title};
- $Result{"body"} .= "".$note." | ";
+ $result .= "
";
+ $result .= "".$cl->{note_title}."" if $cl->{note_title};
+ $result .= "".$note." | ";
if ($cl->{note_title}) {
push @{$toc[@toc]},"".$cl->{note_title}."";
@@ -468,192 +471,343 @@
next;
}
- my $cl_class="cline";
- my $out_class="output";
- if ($cl->{"class"}) {
- $cl_class = $cl->{"class"}."_".$cl_class;
- $out_class = $cl->{"class"}."_".$out_class;
- }
-
- my @new_commands;
- my @new_files;
- @new_commands = split (/\s+/, $cl->{"new_commands"}) if defined $cl->{"new_commands"};
- @new_files = split (/\s+/, $cl->{"new_files"}) if defined $cl->{"new_files"};
my $output="";
- if ($Config{"head_lines"} || $Config{"tail_lines"}) {
- # Partialy output
- my @lines = split '\n', $cl->{"output"};
- # head
- my $mark=1;
+# Выводим верхних строк
+# и нижних строк,
+# если эти параметры существуют
+
+ 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";
}
- # tail
- my $start=$#lines-$Config{"tail_lines"}+1;
- if ($start < 0) {
- $start=0;
- $mark=0;
- }
- if ($start < $Config{"head_lines"}) {
- $start=$Config{"head_lines"};
- $mark=0;
- }
- $output .= $Config{"skip_text"}."\n" if $mark;
- for ($i=$start; $i<= $#lines; $i++) {
+ $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 {
- # Full output
$output .= $cl->{"output"};
}
- #$output .= "^C\n" if ($cl->{"err"} eq "130");
- #
- ##
- ## Начинается собственно вывод
- ##
- #
-
- #
+#
+##
+## Начинается собственно вывод
+##
+#
my ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = localtime($cl->{time});
- next if $Stat{LastCommand} == $cl->{time};
- $Stat{FirstCommand} = $cl->{time} unless $Stat{FirstCommand};
- $Stat{LastCommand} = 0 unless defined $Stat{LastCommand};
- $Stat{TotalTime} += $cl->{time} - $Stat{LastCommand}
- if $cl->{time} - $Stat{LastCommand} < $Config{stat_inactivity_interval};
- $Stat{LastCommand} = $cl->{time};
- $Stat{TotalCommands} = 0 unless $Stat{TotalCommands};
- $Stat{TotalCommands}++;
# Добавляем спереди 0 для удобочитаемости
- $min = "0".$min if $min =~ /^.$/;
+ $min = "0".$min if $min =~ /^.$/;
$hour = "0".$hour if $hour =~ /^.$/;
- $sec = "0".$sec if $sec =~ /^.$/;
+ $sec = "0".$sec if $sec =~ /^.$/;
- $class=$cl->{"out_class"};
- $class =~ s/output$//;
+ #my @new_commands;
+ #my @new_files;
+ #@new_commands = split (/\s+/, $cl->{"new_commands"}) if defined $cl->{"new_commands"};
+ #@new_files = split (/\s+/, $cl->{"new_files"}) if defined $cl->{"new_files"};
- $Stat{ErrorCommands}++
- if $class =~ /wrong/;
+ $class=$cl->{"class"};
+ $Stat{ErrorCommands}++ if $class =~ /wrong/;
+ $Stat{MistypedCommands}++ if $class =~ /mistype/;
- $Result{"body"} .= "\n";
-
- # DAY CHANGE
+# DAY CHANGE
if ( $last_day ne $day) {
- #$Result{"body"} .= "День ",$day," |
";
- $Result{"body"} .= "".$Day_Name[$wday]." |
";
+ if ($last_day) {
+ $result .= "".$Day_Name[$last_wday]."
";
+ #$result .= "Новые команды
";
+ $result .= "\n";
+ $result .= $this_day_result;
+ $result .= "
";
+ }
+
push @toc, "".$Day_Name[$wday]."\n";
$last_day=$day;
+ $last_wday=$wday;
+ $this_day_result = q();
}
- # CONSOLE CHANGE
+ $this_day_result .= "
\n";
+
+
+# CONSOLE CHANGE
if ( $last_tty ne $cl->{"tty"}) {
- my $host;
- #$host = $Sessions{$cl->{local_session_id}}->{user}."@".$Sessions{$cl->{local_session_id}}->{hostname};
- my $body = $cl->{"tty"};
- $body .= " \@$host" if $host;
- $Result{"body"} .= " |
";
+ my $tty = $cl->{"tty"};
+ $this_day_result .= ""
+ .""
+ ." |
";
$last_tty=$cl->{"tty"};
}
- # TIME
- if ($Config{"show_time"} =~ /^y/i) {
- $Result{"body"} .= "".
- $hour. ":". $min. ":". $sec.
- " | ";
- } else {
- $Result{"body"} .= " | "
- }
+# TIME
+ $this_day_result .= $Config{"show_time"} =~ /^y/i
+ ? "$hour:$min:$sec | "
+ : " | ";
- # COMMAND
- $Result{"body"} .= "\n";
- $Result{"body"} .= "\n";
- my $cline = $cl->{"prompt"}.$cl->{"cline"};
+# COMMAND
+ my $hint = make_comment($cl->{"cline"});
+
+ my $cline;
+ $cline = $cl->{"prompt"}.$cl->{"cline"};
$cline =~ s/\n//;
- #$cline .= "(".$Sessions{$cl->{local_session_id}}.")";
-
- my $hint = make_comment($cl->{"cline"});
$cline = "$cline" if $hint;
$cline = "$cline" if !$hint;
- $Result{"body"} .= $cline;
- $Result{"body"} .= " \n";
+ $this_day_result .= " | \n";
+ $this_day_result .= "\n" . $cline . " \n";
+
+# OUTPUT
my $last_command = $cl->{"last_command"};
if (!(
$Config{"suppress_editors"} =~ /^y/i && grep ($_ eq $last_command, @{$Config{"editors"}}) ||
$Config{"suppress_pagers"} =~ /^y/i && grep ($_ eq $last_command, @{$Config{"pagers"}}) ||
$Config{"suppress_terminal"}=~ /^y/i && grep ($_ eq $last_command, @{$Config{"terminal"}})
)) {
-
- $Result{"body"} .= "";
- $Result{"body"} .= $output;
- $Result{"body"} .= " \n";
+ $this_day_result .= "" . $output . " \n";
}
- # DIFF
+# DIFF
if ( $Config{"show_diffs"} =~ /^y/i && $cl->{"diff"}) {
- $Result{"body"} .= " | ";
- $Result{"body"} .= $cl->{"diff"};
- $Result{"body"} .= " | ";
+ $this_day_result .= " | "
+ . $cl->{"diff"}
+ . " | ";
}
-
- #NOTES
+
+#NOTES
if ( $Config{"show_notes"} =~ /^y/i && $cl->{"note"}) {
my $note=$cl->{"note"};
$note =~ s/\n/ \n/msg;
if (not $note =~ s@(http:[a-zA-Z.0-9/_?%-]*)@$1@g) {
- $note =~ s@(www\.[a-zA-Z.0-9/_?%-]*)@$1@g;
- };
+ $note =~ s@(www\.[a-zA-Z.0-9/_?%-]*)@$1@g;
+ };
# Ширину пока не используем
- # $Result{"body"} .= "";
- $Result{"body"} .= "";
- $Result{"body"} .= "".$cl->{note_title}." | " if $cl->{note_title};
- $Result{"body"} .= "".$note." | ";
- $Result{"body"} .= " \n";
+ # $this_day_result .= "";
+ $this_day_result .= "";
+ $this_day_result .= "".$cl->{note_title}." | " if $cl->{note_title};
+ $this_day_result .= "".$note." | ";
+ $this_day_result .= " \n";
}
- # COMMENT
+# COMMENT
if ( $Config{"show_comments"} =~ /^y/i) {
my $comment = make_comment($cl->{"cline"});
if ($comment) {
- $Result{"body"} .= "".
- " | ";
- $Result{"body"} .= "";
- $Result{"body"} .= $comment;
- $Result{"body"} .= " \n";
- $Result{"body"} .= " | ";
+ $this_day_result .= "";
}
}
# Вывод очередной команды окончен
- $Result{"body"} .= "\n";
- $Result{"body"} .= "\n";
+ $this_day_result .= "\n";
+ $this_day_result .= "\n";
}
- $Result{"body"} .= " \n";
+ $result .= "".$Day_Name[$last_wday]."";
+ $result .= "\n";
+ $result .= $this_day_result;
+ $result .= " ";
- #$Result{"stat"} = " ";
+ return ($result, collapse_list (\@toc));
+}
+
+
+
+
+#############
+# print_all
+#
+#
+#
+# In: $_[0] output_filename
+# Out:
+
+
+sub print_all
+{
+ my $output_filename=$_[0];
+
+ my $result;
+ my ($command_lines,$toc) = print_command_lines;
+
+ $result = print_header($toc);
+ $result.= "Журнал" . $command_lines;
+ $result.= "Статистика" . print_stat;
+ $result.= "Справка" . $Html_Help . " ";
+ $result.= "О программе". $Html_About. " ";
+ $result.= print_footer;
+
+ if ($output_filename eq "-") {
+ print $result;
+ }
+ else {
+ open(OUT, ">", $output_filename)
+ or die "Can't open $output_filename for writing\n";
+ print OUT $result;
+ close(OUT);
+ }
+}
+
+#############
+# print_header
+#
+#
+#
+# In: $_[0] Содержание
+# Out: Распечатанный заголовок
+
+sub print_header
+{
+ my $toc = $_[0];
+ my $course_name = $Config{"course-name"};
+ my $course_code = $Config{"course-code"};
+ my $course_date = $Config{"course-date"};
+ my $course_center = $Config{"course-center"};
+ my $course_trainer = $Config{"course-trainer"};
+ my $course_student = $Config{"course-student"};
+
+ my $title = "Журнал лабораторных работ";
+ $title .= " -- ".$course_student if $course_student;
+ if ($course_date) {
+ $title .= " -- ".$course_date;
+ $title .= $course_code ? "/".$course_code
+ : "";
+ }
+ else {
+ $title .= " -- ".$course_code if $course_code;
+ }
+
+ # Управляющая форма
+ my $control_form .= "\n";
+
+ my $result;
+ $result = <
+
+
+
+ $title
+
+
+
+ Журнал лабораторных работ
+HEADER
+ if ( $course_student
+ || $course_trainer
+ || $course_name
+ || $course_code
+ || $course_date
+ || $course_center) {
+ $result .= "";
+ $result .= "Выполнил $course_student " if $course_student;
+ $result .= "Проверил $course_trainer " if $course_trainer;
+ $result .= "Курс " if $course_name
+ || $course_code
+ || $course_date;
+ $result .= "$course_name " if $course_name;
+ $result .= "($course_code)" if $course_code;
+ $result .= ", $course_date " if $course_date;
+ $result .= "Учебный центр $course_center " if $course_center;
+ $result .= " ";
+ }
+
+ $result .= <
+HEADER
+
+ return $result;
+}
+
+
+#############
+# print_footer
+#
+#
+#
+#
+#
+
+sub print_footer
+{
+ return "\n |