"Fossies" - the Fresh Open Source Software Archive 
Member "install-tl-20231127/tlpkg/installer/install-menu-text.pl" (20 Feb 2023, 34342 Bytes) of package /linux/misc/install-tl-unx.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Perl source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 #!/usr/bin/env perl
2 # $Id: install-menu-text.pl 65951 2023-02-20 10:13:03Z siepo $
3 #
4 # Copyright 2007-2022 Norbert Preining, Karl Berry
5 # Copyright 2007-2008 Reinhard Kotucha
6 # This file is licensed under the GNU General Public License version 2
7 # or any later version.
8 #
9 # This file implements the text based menu system for the TeX Live installer.
10
11 use vars qw(@::end_install_hook
12 $::opt_no_cls $::opt_select_repository $::run_menu);
13
14 our %vars;
15 our $opt_in_place;
16 our $tlpdb;
17 our @media_available;
18 our $media;
19 our $previoustlpdb;
20 our @collections_std;
21 our $texlive_release;
22
23 my $MENU_CONTINUE = -1;
24 our $MENU_INSTALL = 0;
25 our $MENU_ABORT = 1;
26 our $MENU_QUIT = 2;
27
28
29 my $RETURN = $MENU_CONTINUE;
30
31 my $portable_toggled = 0;
32 my $ptoggle_alert = "\n".
33 " !! Portable option changed;\n" .
34 " !! Directories have been reinitialized!\n";
35
36 # some strings to describe the different meanings of tlpdbopt_file_assoc
37 $::fileassocdesc[0] = __("None");
38 $::fileassocdesc[1] = __("Only new");
39 $::fileassocdesc[2] = __("All");
40
41 $::deskintdesc[0] = __("None");
42 $::deskintdesc[1] = __("Menu shortcuts");
43 if (wndws()) { $::deskintdesc[2] = __("Launcher"); }
44
45 sub clear_screen {
46 return 0 if ($::opt_no_cls);
47 system (unix() ? 'clear' : 'cls');
48 }
49
50 sub string_to_list {
51 my $string=shift;
52 return split(//, $string);
53 }
54
55 sub button { # for main menu: 1 char
56 my $val=shift;
57 my $vals=shift; # array ref to descriptions of possible values
58 if (defined $vals) {
59 return "[$val]";
60 } else { # just yes/no
61 return ($val)? '[X]':'[ ]';
62 }
63 }
64
65 sub obutton { # for options menu: more chars allowed
66 my $val=shift;
67 my $vals=shift; # array ref to descriptions of possible values
68 $vals = [' ', 'X'] unless defined $vals;
69 return "[$$vals[$val]]";
70 }
71
72 sub hbar {
73 return '=' x79, "\n";
74 }
75
76 sub toggle {
77 my $var=shift;
78 my $vals=shift; # array ref to descriptions of possible values
79 $vals = [' ', 'X'] unless defined $vals;
80 my $n_vals = @$vals;
81 $vars{$var} += 1;
82 $vars{$var} = 0 unless $vars{$var} < $n_vals;
83 }
84
85 sub menu_head {
86 my $text = shift;
87 clear_screen;
88 print hbar(), "$text\n\n";
89 }
90
91 sub other_options {
92 my @options=@_;
93 my %opts=(
94 '-' => 'deselect all',
95 '+' => 'select all',
96 'R' => 'return to main menu',
97 'P' => 'save installation profile to \'texlive.profile\' and exit',
98 'Q' => 'quit'
99 );
100
101 $opts{'I'}=$vars{'instopt_portable'} ? 'start portable installation' :
102 'start installation to hard disk';
103
104 print "\nActions:";
105 if ($options[$#options] eq 'diskspace') {
106 pop @options;
107 calc_depends ();
108 print " (disk space required: $vars{'total_size'} MB)";
109 }
110 print "\n";
111
112 for my $option (@options) {
113 if (defined $opts{"$option"}) {
114 printf " <%s> %s\n", $option, $opts{$option};
115 } else {
116 die "other_options: $opts{$option} undefined.\n";
117 }
118 }
119 }
120
121 sub prompt {
122 my $prompt = shift;
123 print "\n$prompt: ";
124 my $answer = <STDIN>;
125 $answer = "q" if !defined($answer);
126 chomp($answer);
127 return "$answer";
128 }
129
130 # The menu loop. A menu is a function. Its return value is a
131 # reference to another menu or to itself.
132 sub run_menu_text {
133 my (@args) = @_;
134 my $default = 0;
135 # select mirror if -select-mirror is given
136 if ($::opt_select_repository) {
137 # network is always available
138 my @mirror_list = TeXLive::TLUtils::create_mirror_list();
139 print "Please select a repository:\n";
140 print "Network repositories:" if ($#media_available >= 0);
141 my @sel_to_index;
142 my $selind = 0;
143 # this is for 0 mirror.ctan.org, but it is printed last!
144 push @sel_to_index, 0;
145 $selind++;
146 for my $i (0..$#mirror_list) {
147 if ($mirror_list[$i] !~ m/^ /) {
148 print "\n$mirror_list[$i]\n";
149 } else {
150 print " " if 1 <= $selind && $selind <= 9; # align
151 print "[$selind] $mirror_list[$i]\n";
152 push @sel_to_index, $i;
153 $selind++;
154 }
155 }
156 print "----\n";
157 print "[0] default mirror https://mirror.ctan.org\n";
158 my $local_ind = "a";
159 if ($#media_available >= 0) {
160 print "Local repositories:\n";
161 # we have some local media present, propose to use it
162 for my $l (@media_available) {
163 my ($a, $b) = split ('#', $l);
164 if ($a eq 'local_compressed') {
165 print "[$local_ind] compressed archive at $b\n";
166 $default = $local_ind;
167 #$local_ind = chr(ord($local_ind)+1);
168 $local_ind++;
169 } elsif ($a eq 'local_uncompressed') {
170 print "[$local_ind] uncompressed archive at $b\n";
171 $default = $local_ind;
172 $local_ind++;
173 } elsif ($a eq 'NET') {
174 print "[$local_ind] cmd line repository: $b\n";
175 $default = $local_ind;
176 $local_ind++;
177 } else {
178 warn "$0: Unknown media $l";
179 }
180 }
181 }
182 print "[q] quit\n";
183 $selind--;
184 my $selstr = "Your selection ";
185 if ($local_ind ne "a") {
186 # we got at least some local repository
187 if ($local_ind eq "b") {
188 $selstr .= "(a,0-$selind,q)";
189 $local_ind = chr(ord($local_ind)-1);
190 } else {
191 # that does not work!!!
192 #$local_ind--;
193 $local_ind = chr(ord($local_ind)-1);
194 $selstr .= "(a-$local_ind,0-$selind,q)";
195 }
196 }
197 $selstr .= " [$default]: ";
198 my $got_answer = 0;
199 my $ans = undef;
200 while (!defined($ans)) {
201 print $selstr;
202 $ans = readline(*STDIN);
203 if (!defined($ans)) {
204 print "Please select `q' to quit the program!\n";
205 } else {
206 chomp($ans);
207 $ans = $default if ($ans eq "");
208 if ($ans =~ m/^[0-9]+$/) {
209 if (0 <= $ans && $ans <= $selind) {
210 my $mfull;
211 if ($ans == 0) {
212 $::init_remote_needed = 'ctan';
213 } else {
214 # only if something else but the predefined mirror is selected
215 # we something here
216 $mfull = TeXLive::TLUtils::extract_mirror_entry($mirror_list[$sel_to_index[$ans]]);
217 print "selected mirror: ", $mfull, "\n";
218 $::init_remote_needed = $mfull;
219 }
220 }
221 } elsif ($ans =~ m/^[a-$local_ind]$/) {
222 my $i = ord($ans) - ord('a');
223 my $t = $media_available[$i];
224 $t =~ s/^[^#]*#//;
225 $::init_remote_needed = $t;
226 } elsif ($ans eq 'q' || $ans eq 'Q') {
227 print "Goodbye.\n";
228 exit 0;
229 } else {
230 print "Not a valid answer: $ans.\n";
231 $ans = undef;
232 }
233 }
234 }
235 }
236
237 # run remote init
238 if (!do_remote_init($::init_remote_needed)) {
239 warn "\n";
240 warn "Please select a different mirror! See info above.\n";
241 print STDERR "Press Enter to exit... ";
242 my $ans = readline (*STDIN);
243 exit (1);
244 }
245
246 # the text mode installer does not take look at any argument
247 # except -old-installation-found.
248 while (@args) {
249 my $f = shift @args;
250 if ($f =~ m/^-old-installation-found=(.*)$/) {
251 my $dn = $1;
252 print "\nAn existing installation of TeX Live has been found in $dn\n";
253 print "
254 If you want its selection of schemes/collections and various options
255 to be used, press `y', otherwise anything else.
256
257 Import settings from previous TeX Live installation: (y/n): ";
258 chomp(my $yn = <STDIN>);
259 if (defined $yn && $yn =~ m/^y$/i) {
260 import_settings_from_old_tlpdb($dn);
261 }
262 }
263 }
264 my $menu=\&main_menu;
265 while ($RETURN == $MENU_CONTINUE) {
266 $menu=$menu->();
267 }
268 return($RETURN);
269 }
270 $::run_menu = \&run_menu_text;
271
272 sub binary_menu {
273 my %command=(
274 'self' => \&binary_menu,
275 'R' => \&main_menu,
276 'Q' => \&quit
277 );
278
279 my @binaries;
280 my @keys=string_to_list "abcdefghijklmopstuvwxyz";
281 my $index=0;
282 my %keyval;
283 my $selected_platform;
284
285 menu_head "Available platforms:";
286
287 foreach my $key (keys %vars) {
288 if ($key =~ /binary_(.*)/) {
289 push @binaries, $1;
290 }
291 }
292
293 @binaries=sort TeXLive::TLUtils::sort_archs @binaries;
294
295 foreach my $binary (@binaries) {
296 printf " %s %s %s (%s)\n", $keys[$index],
297 button($vars{"binary_$binary"}),
298 platform_desc($binary),
299 "$binary";
300 $keyval{"$keys[$index]"} = "binary_$binary";
301 ++$index;
302 }
303 other_options qw(- + R Q diskspace);
304
305 my $answer = prompt 'Enter letter(s) to (de)select platforms';
306
307 my @keystrokes=string_to_list $answer;
308
309 foreach my $keystroke (@keystrokes) {
310 if ($keystroke eq '-') {
311 for my $binary (@binaries) {
312 $vars{"binary_$binary"}=0 if defined $vars{"binary_$binary"};
313 }
314 }
315 if ($keystroke eq '+') {
316 for my $binary (@binaries) {
317 $vars{"binary_$binary"}=1 if defined $vars{"binary_$binary"};
318 }
319 }
320 if (defined $keyval{$keystroke}) {
321 toggle "$keyval{$keystroke}";
322 } elsif (!defined $command{"\u$answer"}) {
323 print "Unknown command: $answer\n\n";
324 }
325 }
326 if ($vars{"binary_windows"}) {
327 $vars{"collection-wintools"} = 1;
328 } else {
329 $vars{"collection-wintools"} = 0;
330 }
331 if (defined $command{"\u$answer"}) {
332 return $command{"\u$answer"}->();
333 } else {
334 return $command{'self'}->();
335 }
336 }
337
338
339 sub scheme_menu {
340 my %command=(
341 'self' => \&scheme_menu,
342 'R' => \&main_menu,
343 'Q' => \&quit
344 );
345
346 my @schemes;
347 my @keys=string_to_list "abcdefghijklmnopstuvwxyz";
348 my %keyval;
349 my $index=0;
350
351 menu_head 'Select scheme:';
352
353 @schemes = schemes_ordered_for_presentation();
354 foreach my $pkg (@schemes) {
355 $vars{"$pkg"}=($vars{'selected_scheme'} eq $pkg)? 1:0;
356 }
357 push @schemes, "scheme-custom";
358
359 foreach my $scheme (@schemes) {
360 $keyval{$keys[$index]}="$scheme";
361 if ($scheme ne "scheme-custom") {
362 my $tlpobj = $tlpdb->get_package("$scheme");
363 printf " %s %s %s\n", $keys[$index], button($vars{"$scheme"}),
364 $tlpobj->shortdesc;
365 } else {
366 printf " %s %s custom selection of collections\n",
367 $keys[$index], button($vars{'selected_scheme'} eq "scheme-custom");
368 }
369 ++$index;
370 }
371
372 select_scheme($vars{'selected_scheme'});
373
374 if ($vars{"binary_windows"}) {
375 $vars{"collection-wintools"} = 1;
376 } else {
377 $vars{"collection-wintools"} = 0;
378 }
379
380 other_options qw(R Q diskspace);
381 my $answer = prompt 'Enter letter to select scheme';
382
383 if (defined $keyval{"$answer"}) {
384 $vars{'selected_scheme'}=$keyval{"$answer"};
385 select_scheme($vars{'selected_scheme'});
386 return $command{'self'}->();
387 }
388 if (defined $command{"\u$answer"}) {
389 return $command{"\u$answer"}->();
390 } else {
391 print "Unknown command: $answer\n\n";
392 return $command{'self'}->();
393 }
394 }
395
396
397 sub collection_menu {
398 my %command=(
399 'self' => \&collection_menu,
400 'R' => \&main_menu,
401 'Q' => \&quit
402 );
403
404 my @collections;
405 my @keys=string_to_list "abcdefghijklmnopstuvwxyzABCDEFGHIJKLMNOPSTUVWXYZ";
406 my %keyval;
407 my $index=0;
408 my @coll_short_desc;
409 my @coll_long_desc;
410
411 menu_head 'Select collections:';
412
413 @collections=sort @collections_std;
414
415 foreach my $collection (@collections) {
416 next if ($collection eq 'collection-perl');
417 my $tlpobj = $tlpdb->get_package("$collection");
418 if (length $tlpobj->shortdesc>30) {
419 push @coll_long_desc, $collection;
420 } else {
421 push @coll_short_desc, $collection;
422 }
423 }
424 my $singlecolumn_index=@coll_short_desc-1;
425
426 ##<cols=2>
427 my $lines=@coll_short_desc/2;
428 ++$lines if (@coll_short_desc%2);
429 for (0..$lines-1) {
430 $index=$_;
431 my $collection=$coll_short_desc[$index];
432 my $tlpobj = $tlpdb->get_package("$collection");
433 $keyval{$keys[$index]}="$collection";
434 printf " %s %s %-33s", $keys[$index], button($vars{"$collection"}),
435 substr($tlpobj->shortdesc,0,33);
436 if (defined $coll_short_desc[$index+$lines]) {
437 my $collection=$coll_short_desc[$index+$lines];
438 my $tlpobj=$tlpdb->get_package("$collection");
439 $keyval{$keys[$index+$lines]}="$collection";
440 printf " %s %s %-32s\n", $keys[$index+$lines],
441 button($vars{"$collection"}), substr($tlpobj->shortdesc,0,32);
442 } else {
443 print "\n";
444 }
445 }
446 ##</cols=2>
447 $index=$singlecolumn_index;
448 # print "\n$index\n\n";
449 foreach my $collection (@coll_long_desc) {
450 my $tlpobj=$tlpdb->get_package("$collection");
451 $keyval{$keys[$index+1]}="$collection";
452 printf " %s %s %s\n", $keys[$index+1], button($vars{"$collection"}),
453 $tlpobj->shortdesc;
454 ++$index;
455 }
456 ##</cols=1>
457
458 other_options qw(- + R Q diskspace);
459 my $answer = prompt 'Enter letter(s) to (de)select collection(s)';
460
461 my @keystrokes=string_to_list $answer;
462
463 foreach my $keystroke (@keystrokes) {
464 if ($keystroke eq '-') {
465 for my $collection (@collections) {
466 $vars{"$collection"}=0 if defined $vars{"$collection"};
467 }
468 }
469 if ($keystroke eq '+') {
470 for my $collection (@collections) {
471 $vars{"$collection"}=1 if defined $vars{"$collection"};
472 }
473 }
474 if (defined $keyval{$keystroke}) {
475 toggle "$keyval{$keystroke}";
476 } elsif (!defined $command{"\u$answer"}) {
477 print "Unknown command: $answer\n\n";
478 }
479 }
480
481 if (defined $command{"\u$answer"}) {
482 # if we play around with collections we also select custom-scheme
483 # but we do not switch back to originally afterwards, too complicated
484 # to be done
485 select_scheme("scheme-custom");
486 return $command{"\u$answer"}->();
487 } else {
488 return $command{'self'}->();
489 }
490 }
491
492
493 sub directories_menu
494 {
495 my %command=(
496 'self' => \&directories_menu,
497 'R' => \&main_menu,
498 'Q' => \&quit
499 );
500
501 menu_head "Directories customization:";
502 if (!TeXLive::TLUtils::texdir_check($vars{'TEXDIR'}, 1)) {
503 print "!! The default location as given below is forbidden or
504 !! can't be written to.
505 !! Either change the destination directory using <1> or create it
506 !! outside this script.
507 ";
508 }
509 my $texmfdir = $vars{'TEXDIR'} .
510 ($vars{'TEXDIR'} =~ /\/$/ ? 'texmf-dist' : '/texmf-dist');
511 if (!$opt_in_place) {
512 print <<"EOF";
513 <1> TEXDIR: $vars{'TEXDIR'}
514 main tree: $texmfdir
515 EOF
516 } else {
517 print <<"EOF";
518 TEXDIR: $vars{'TEXDIR'}
519 main tree: $texmfdir
520 EOF
521 }
522 if (!$vars{'instopt_portable'}) {
523 print <<"EOF";
524
525 <2> TEXMFLOCAL: $vars{'TEXMFLOCAL'}
526 <3> TEXMFSYSVAR: $vars{'TEXMFSYSVAR'}
527 <4> TEXMFSYSCONFIG: $vars{'TEXMFSYSCONFIG'}
528
529 <5> TEXMFVAR: $vars{'TEXMFVAR'}
530 <6> TEXMFCONFIG: $vars{'TEXMFCONFIG'}
531 <7> TEXMFHOME: $vars{'TEXMFHOME'}
532
533 EOF
534
535 if (wndws()) {
536 print " Note: ~ will expand to %USERPROFILE%\n";
537 } else {
538 print " Note: ~ will expand to \$HOME (or to %USERPROFILE% on Windows)\n";
539 }
540 }
541
542 other_options qw(R Q);
543 my $answer = prompt 'Enter command';
544
545 if ("\u$answer" eq '1' and !$opt_in_place) {
546 print "New value for TEXDIR [$vars{'TEXDIR'}]: ";
547 $answer = &input_dirname ();
548 # update free space information
549 if ($answer ne $vars{'TEXDIR'}) {
550 $vars{'free_size'} = TeXLive::TLUtils::diskfree($answer);
551 }
552 $vars{'TEXDIR'} = $answer if $answer ne "";
553 my $texdirnoslash;
554 if ($vars{'TEXDIR'}=~/^(.*)\/$texlive_release$/) {
555 $texdirnoslash = $1;
556 $vars{'TEXMFLOCAL'}="$texdirnoslash/texmf-local";
557 $vars{'TEXMFSYSVAR'}="$texdirnoslash/$texlive_release/texmf-var";
558 $vars{'TEXMFSYSCONFIG'}="$texdirnoslash/$texlive_release/texmf-config";
559 } elsif ($vars{'TEXDIR'}=~/^(.*)$/) {
560 $texdirnoslash = $1;
561 $texdirnoslash =~ s!/$!!;
562 $vars{'TEXMFLOCAL'}="$texdirnoslash/texmf-local";
563 $vars{'TEXMFSYSVAR'}="$texdirnoslash/texmf-var";
564 $vars{'TEXMFSYSCONFIG'}="$texdirnoslash/texmf-config";
565 }
566 return $command{'self'};
567
568 } elsif ("\u$answer" eq '2' and !$vars{'instopt_portable'}) {
569 print "New value for TEXMFLOCAL [$vars{'TEXMFLOCAL'}]: ";
570 $answer = &input_dirname ();
571 $vars{'TEXMFLOCAL'} = $answer if $answer ne "";
572 return $command{'self'};
573
574 } elsif ("\u$answer" eq '3' and !$vars{'instopt_portable'}) {
575 print "New value for TEXMFSYSVAR [$vars{'TEXMFSYSVAR'}]: ";
576 $answer = &input_dirname ();
577 $vars{'TEXMFSYSVAR'} = $answer if $answer ne "";
578 return $command{'self'};
579
580 } elsif ("\u$answer" eq '4' and !$vars{'instopt_portable'}) {
581 print "New value for TEXMFSYSCONFIG [$vars{'TEXMFSYSCONFIG'}]: ";
582 $answer = &input_dirname ();
583 $vars{'TEXMFSYSCONFIG'} = $answer if $answer ne "";
584 return $command{'self'};
585
586 } elsif ("\u$answer" eq '5' and !$vars{'instopt_portable'}) {
587 print "New value for TEXMFVAR [$vars{'TEXMFVAR'}]: ";
588 $answer = &input_dirname ("noexpansion");
589 $vars{'TEXMFVAR'} = $answer if $answer ne "";
590 return $command{'self'};
591
592 } elsif ("\u$answer" eq '6' and !$vars{'instopt_portable'}) {
593 print "New value for TEXMFCONFIG [$vars{'TEXMFCONFIG'}]: ";
594 $answer = &input_dirname ("noexpansion");
595 $vars{'TEXMFCONFIG'} = $answer if $answer ne "";
596 return $command{'self'};
597
598 } elsif ("\u$answer" eq '7' and !$vars{'instopt_portable'}) {
599 print "New value for TEXMFHOME [$vars{'TEXMFHOME'}]: ";
600 $answer = &input_dirname ("noexpansion");
601 $vars{'TEXMFHOME'} = $answer if $answer ne "";
602 return $command{'self'};
603 }
604
605 if (defined $command{"\u$answer"}) {
606 return $command{"\u$answer"}->();
607 } else {
608 print "Unknown command: $answer\n\n";
609 return $command{'self'}->();
610 }
611 }
612
613
614 # Helper function to read a directory name and clean it up.
615 # Unless NO_EXPANSION is true, convert to absolute path.
616 #
617 sub input_dirname
618 {
619 my $noexpansion = shift;
620 chomp (my $answer = <STDIN>);
621 return "" if $answer eq "";
622
623 $answer =~ s!\\!/!g if wndws(); # switch to forward slashes
624
625 if (!$noexpansion) {
626 $answer = TeXLive::TLUtils::expand_tilde($answer);
627 }
628
629 if ($answer !~ m/^~/) {
630 # relative paths are unlikely to work in texmf.cnf, et al.,
631 # and don't have any apparent practical use. Convert to absolute.
632 if (! File::Spec->file_name_is_absolute($answer)) {
633 $answer = TeXLive::TLUtils::tl_abs_path($answer);
634 $answer = "" unless defined $answer;
635 }
636 }
637 return $answer;
638 }
639
640
641 $vars{'page'}=0;
642
643 sub html2text {
644 my $filename=shift;
645 my @text;
646 open IN, "$filename";
647 @all_lines=<IN>;
648 close IN;
649 chomp @all_lines;
650
651 my $itemcnt;
652 my $ordered_list=0;
653 my $h1_indent=25;
654 my $h2_indent=3;
655 my $h3_indent=6;
656
657 for (@all_lines) {
658 next if /DOCTYPE/;
659 next if /<!--/;
660 next if /<title/i;
661 next if /<\/?body/i;
662 next if /<\/?html/i;
663 next if /<\/?head/i;
664 next if /<\/?meta/i;
665 next if /^\s*$/; # ignore empty lines
666
667 s/<i>/"/gi; s/<\/i>/"/gi; # italics
668 s/<tt>/'/gi; s/<\/tt>/'/gi; # typewriter
669 s/<p>.*//gi; # paragraphs
670 s/<\/ul>.*//gi; # unsorted lists
671 s/<\/ol>.*//gi; # ordered lists
672 s/—/--/gi; # mdash
673 s/</</gi; s/>/>/gi; # < and >
674 if (/<h1>(.*?)<\/h1>/i) {
675 push @text, " " x $h1_indent. "$1\n";
676 push @text, " " x $h1_indent. "=" x (length $1). "\n";
677 push @text, "\n";
678 } elsif (/<h2>(.*?)<\/h2>/i) {
679 push @text, "\n";
680 push @text, " " x $h2_indent. "$1\n";
681 push @text, " " x $h2_indent. "~" x (length $1). "\n";
682 push @text, "\n";
683 } elsif (/<h3>(.*?)<\/h3>/i) {
684 push @text, "\n";
685 push @text, " " x $h3_indent. "$1\n";
686 push @text, " " x $h3_indent. "-" x (length $1). "\n";
687 push @text, "\n";
688 } elsif (/<ol>/i) {
689 $ordered_list=1;
690 $itemcnt=1;
691 } elsif (/<ul>/i) {
692 $ordered_list=0;
693 } elsif (/^\s*<li>\s*(.*)/) {
694 if ($ordered_list) {
695 push @text, "\n";
696 push @text, " $itemcnt. $1\n";
697 ++$itemcnt;
698 } else {
699 push @text, "\n";
700 push @text, " * $1\n";
701 }
702 } else {
703 push @text, "$_\n";
704 }
705 }
706 return @text;
707 }
708
709
710 # dumping the html doc to stdout does not seem very helpful,
711 # and did not work for years with no one noticing, so this
712 # function is no longer used.
713 sub help_menu {
714 my %command=(
715 'self' => \&help_menu,
716 'R' => \&main_menu,
717 'Q' => \&quit
718 );
719 my $installer_help = "notused/tlpkg/installer/install-tl.html";
720
721 clear_screen;
722
723 my @text=html2text ($installer_help);
724 my $lines=(@text);
725 my $overlap=3;
726 my $lps=32; # lines per screen - overlap
727 my $firstline=$vars{'page'}*$lps;
728 my $lastline=$firstline+$lps+$overlap;
729 my $line=0;
730 # print "<<<$firstline>>> <<<$lastline>>>\n";
731 for (@text) {
732 print "$_" if ($line>=$firstline and $line<=$lastline);
733 ++$line;
734 }
735 print "\n", hbar,
736 " <T> top <N> next page <P> previous page <R> return"
737 . " <Q> quit --", $vars{'page'}+1, "--\n";
738
739 my $answer = prompt 'Enter command';
740
741 if ("\u$answer" eq 'T') {
742 $vars{'page'}=0;
743 return $command{'self'};
744
745 } elsif ("\u$answer" eq 'N') {
746 $vars{'page'}+=1 unless $lastline>$lines;
747 return $command{'self'};
748
749 } elsif ("\u$answer" eq 'P') {
750 $vars{'page'}-=1 if $vars{'page'}>=1;
751 return $command{'self'};
752
753 } elsif (defined $command{"\u$answer"}) {
754 return $command{"\u$answer"};
755
756 } else {
757 print "Unknown command: $answer\n\n";
758 return $command{'self'};
759 }
760 }
761
762
763 sub options_menu {
764 my $b_path=obutton($vars{'instopt_adjustpath'});
765 my $b_doc=obutton($vars{'tlpdbopt_install_docfiles'});
766 my $b_src=obutton($vars{'tlpdbopt_install_srcfiles'});
767 my $b_fmt=obutton($vars{'tlpdbopt_create_formats'});
768 my $b_letter=obutton($vars{'instopt_letter'});
769 my $b_adjustrepo=obutton($vars{'instopt_adjustrepo'});
770 my $b_deskint=obutton(
771 $vars{'tlpdbopt_desktop_integration'}, \@::deskintdesc);
772 my $b_admin=obutton($vars{'tlpdbopt_w32_multi_user'});
773 my $b_addoneditor=obutton($vars{'collection-texworks'});
774 my $b_restricted=obutton($vars{'instopt_write18_restricted'});
775
776 my $sys_bin=$vars{'tlpdbopt_sys_bin'};
777 my $sys_man=$vars{'tlpdbopt_sys_man'};
778 my $sys_info=$vars{'tlpdbopt_sys_info'};
779
780 my $t_sys_bin=($vars{'instopt_adjustpath'})? $vars{'tlpdbopt_sys_bin'}:'';
781 my $t_sys_man=($vars{'instopt_adjustpath'})? $vars{'tlpdbopt_sys_man'}:'';
782 my $t_sys_info=($vars{'instopt_adjustpath'})? $vars{'tlpdbopt_sys_info'}:'';
783
784 my %command=(
785 'self' => \&options_menu,
786 'R' => \&main_menu,
787 'Q' => \&quit
788 );
789
790 clear_screen;
791 menu_head "Options customization:";
792
793 print <<"EOF";
794 <P> use letter size instead of A4 by default: $b_letter
795 <E> execution of restricted list of programs: $b_restricted
796 <F> create all format files: $b_fmt
797 EOF
798 ;
799 if ($vars{'doc_splitting_supported'} and !$opt_in_place) {
800 print " <D> install font/macro doc tree: $b_doc\n";
801 }
802 if ($vars{'src_splitting_supported'} and !$opt_in_place) {
803 print " <S> install font/macro source tree: $b_src\n";
804 }
805 if (!$vars{'instopt_portable'}) {
806 if (unix() || $::opt_all_options) {
807 print <<"EOF";
808 <L> create symlinks in standard directories: $b_path
809 binaries to: $t_sys_bin
810 manpages to: $t_sys_man
811 info to: $t_sys_info
812 EOF
813 ;
814 } else {
815 print <<"EOF";
816 <L> adjust registry entry for path: $b_path
817 EOF
818 ;
819 }
820 if ((wndws() && !$vars{'instopt_portable'}) || $::opt_all_options) {
821 print " <M> Start menu shortcuts / launcher: ".obutton(
822 $vars{'tlpdbopt_desktop_integration'}, \@::deskintdesc)."\n";
823 print " <N> update file associations: ".obutton(
824 $vars{'tlpdbopt_file_assocs'}, \@::fileassocdesc)."\n";
825 if ($::opt_all_options || TeXLive::TLWinGoo::admin()) {
826 # if we are admin we allow normal user installation, too
827 print " <U> make installation available to all users: $b_admin\n";
828 }
829 }
830 }
831 if (wndws() || $::opt_all_options) {
832 print " <W> install TeXworks front end: $b_addoneditor\n";
833 }
834 if ($media ne "NET") {
835 print " <Y> after install, set CTAN as source for package updates: $b_adjustrepo\n";
836 }
837 other_options qw(R Q diskspace);
838 my $answer = prompt 'Enter command';
839
840 # instopt_adjustpath
841
842 if (unix()) {
843 if (("\u$answer" eq 'L') and !$vars{'instopt_portable'}) {
844 my $home = TeXLive::TLUtils::get_user_home();
845 toggle 'instopt_adjustpath';
846 if ($vars{'instopt_adjustpath'}) {
847 print "New value for binary directory [$sys_bin]: ";
848 chomp($answer=<STDIN>);
849 $vars{'tlpdbopt_sys_bin'} = "$answer" if (length $answer);
850 $vars{'tlpdbopt_sys_bin'} =~ s@\\@/@g if (wndws());
851 $vars{'tlpdbopt_sys_bin'} =~ s/^~/$home/;
852 if ($vars{'tlpdbopt_sys_bin'}=~/^(.*)\/bin$/) {
853 $vars{'tlpdbopt_sys_man'}="$1/man";
854 $vars{'tlpdbopt_sys_info'}="$1/info";
855 }
856 print "New value for man directory [$vars{'tlpdbopt_sys_man'}]: ";
857 chomp($answer=<STDIN>);
858 $vars{'tlpdbopt_sys_man'}="$answer" if (length $answer);
859 $vars{'tlpdbopt_sys_man'} =~ s@\\@/@g if (wndws());
860 $vars{'tlpdbopt_sys_man'} =~ s/^~/$home/;
861
862 print "New value for info directory [$vars{'tlpdbopt_sys_info'}]: ";
863 chomp($answer=<STDIN>);
864 $vars{'tlpdbopt_sys_info'}="$answer" if (length $answer);
865 $vars{'tlpdbopt_sys_info'} =~ s@\\@/@g if (wndws());
866 $vars{'tlpdbopt_sys_info'} =~ s/^~/$home/;
867 }
868 return $command{'self'};
869 }
870 } else {
871 if (("\u$answer" eq 'L') and !$vars{'instopt_portable'}) {
872 my $home = TeXLive::TLUtils::get_user_home;
873 toggle 'instopt_adjustpath';
874 return $command{'self'};
875 }
876 }
877
878 # # tlpdbopt_desktop_integration, tlpdbopt_file_assocs
879 #
880 # if (wndws() || $::opt_all_options) {
881 # if ("\u$answer" eq 'M' and !$vars{'instopt_portable'}) {
882 # toggle 'tlpdbopt_desktop_integration';
883 # return $command{'self'};
884 #
885 # } elsif ("\u$answer" eq 'N' and !$vars{'instopt_portable'}) {
886 # print "New value for file_assocs:\n";
887 # print " 0 -- don't tweak the file associations\n";
888 # print " 1 -- only add new file associations, don't overwrite old ones\n";
889 # print " 2 -- always create file associations to TeX Live programs\n";
890 # print "New value for file_assocs [$vars{'tlpdbopt_file_assocs'}]: ";
891 # chomp (my $a = <STDIN>);
892 # if ($a eq "0" || $a eq "1" || $a eq "2") {
893 # $vars{'tlpdbopt_file_assocs'} = $a;
894 # }
895 # return $command{'self'};
896 #
897 # } elsif ("\u$answer" eq 'U' and !$vars{'instopt_portable'}) {
898 # toggle 'tlpdbopt_w32_multi_user';
899 # return $command{'self'};
900 # }
901 # }
902
903 # other options
904
905 if (("\u$answer" eq 'M') && !$vars{'instopt_portable'}) {
906 toggle ('tlpdbopt_desktop_integration', \@::deskintdesc);
907 return $command{'self'};
908
909 } elsif (("\u$answer" eq 'N') && !$vars{'instopt_portable'}) {
910 toggle ('tlpdbopt_file_assocs', \@::fileassocdesc);
911 return $command{'self'};
912
913 } elsif ("\u$answer" eq 'P') {
914 toggle 'instopt_letter';
915 return $command{'self'};
916
917 } elsif ("\u$answer" eq 'F') {
918 toggle 'tlpdbopt_create_formats';
919 return $command{'self'};
920
921 } elsif ("\u$answer" eq 'E') {
922 toggle 'instopt_write18_restricted';
923 return $command{'self'};
924
925 } elsif ("\u$answer" eq 'S' and !$opt_in_place) {
926 toggle 'tlpdbopt_install_srcfiles';
927 return $command{'self'};
928
929 } elsif ("\u$answer" eq 'D' and !$opt_in_place) {
930 toggle 'tlpdbopt_install_docfiles';
931 return $command{'self'};
932
933 } elsif (defined $command{"\u$answer"}) {
934 return $command{"\u$answer"};
935
936 } elsif (("\u$answer" eq 'W') && ($::opt_all_options || wndws()) &&
937 !$opt_in_place ) {
938 toggle 'collection-texworks';
939 return $command{'self'};
940
941 } elsif ("\u$answer" eq 'Y' and $media ne "NET") {
942 toggle 'instopt_adjustrepo';
943 return $command{'self'};
944
945 } else {
946 print "Unknown or unsupported command: $answer\n\n";
947 return $command{'self'};
948 }
949 }
950
951
952 sub quit {
953 exit 0;
954 $RETURN = $MENU_QUIT;
955 }
956
957 sub do_install {
958 my $reserve = 100;
959 my $doit = 1;
960 if ($vars{'free_size'} > 0
961 && $vars{'free_size'} + $reserve < $vars{'total_size'}) {
962 print STDERR <<"EOF";
963 *** WARNING ****************************************************
964 The installation requires $vars{'total_size'}M of disk space
965 but only $vars{'free_size'}M is available.
966
967 You probably want to either clean up the destination filesystem,
968 or choose a different installation location,
969 or reduce what gets installed.
970
971 Press Enter to return to the menu, or i to install anyway.
972 ****************************************************************
973 EOF
974 my $ans = readline (*STDIN);
975 $doit = 0;
976 chomp($ans);
977 if ($ans eq "i" or $ans eq "I") {
978 $doit = 1;
979 }
980 }
981 if ($doit) {
982 # set env variable to make install-tl not trip over
983 $ENV{'TEXLIVE_INSTALL_NO_DISKCHECK'} = 1;
984 $RETURN = $MENU_INSTALL;
985 } else {
986 main_menu();
987 }
988 }
989
990 sub toggle_portable {
991 if ($vars{'instopt_portable'}) {
992 $vars{'instopt_portable'} = 0;
993 $vars{'tlpdbopt_desktop_integration'} = 0;
994 $vars{'instopt_adjustpath'} = 0;
995 $vars{'tlpdbopt_file_assocs'} = 0;
996 $vars{'tlpdbopt_w32_multi_user'} = 0;
997 } else {
998 $vars{'instopt_portable'} = 1;
999 $vars{'tlpdbopt_desktop_integration'} = 1;
1000 $vars{'instopt_adjustpath'} = 1;
1001 $vars{'tlpdbopt_file_assocs'} = 1;
1002 $vars{'tlpdbopt_w32_multi_user'} = 1;
1003 }
1004 $portable_toggled = 1;
1005 set_texlive_default_dirs(); # this sub tests for portable and in_place
1006 main_menu;
1007 }
1008
1009 sub callback_save_profile {
1010 create_profile("texlive.profile");
1011 print "Installation profile saved to 'texlive.profile', exiting.\n";
1012 exit(0);
1013 }
1014
1015 sub main_menu {
1016 my $this_platform=platform_desc($vars{'this_platform'});
1017
1018 my $b_path=button($vars{'instopt_adjustpath'});
1019 my $b_doc=button($vars{'tlpdbopt_install_docfiles'});
1020 my $b_src=button($vars{'tlpdbopt_install_srcfiles'});
1021 my $b_fmt=button($vars{'tlpdbopt_create_formats'});
1022 my $b_letter=button($vars{'instopt_letter'});
1023 my $b_deskint=button($vars{'tlpdbopt_desktop_integration'}, \@::deskintdesc);
1024 if (wndws()) {
1025 my $b_fileassoc=button($vars{'tlpdbopt_file_assocs'}, \@::fileassocdesc);
1026 }
1027 my $b_admin=button($vars{'tlpdbopt_w32_multi_user'});
1028 my $b_addoneditor=button($vars{'collection-texworks'});
1029 my $b_restricted=button($vars{'instopt_write18_restricted'});
1030 my $b_adjustrepo=button($vars{'instopt_adjustrepo'});
1031
1032 my $warn_nobin;
1033
1034 $warn_nobin=set_install_platform;
1035
1036 $vars{'n_systems_selected'}=0;
1037 $vars{'n_collections_selected'}=0;
1038 foreach my $key (keys %vars) {
1039 if ($key=~/^binary.*/) {
1040 ++$vars{'n_systems_selected'} if $vars{$key}==1;
1041 }
1042 if ($key=~/^collection/) {
1043 ++$vars{'n_collections_selected'} if $vars{$key}==1;
1044 }
1045 }
1046 calc_depends();
1047
1048 my %command = (
1049 'self' => \&main_menu,
1050 'D' => \&directories_menu,
1051 'I' => \&do_install,
1052 'O' => \&options_menu,
1053 'Q' => \&quit,
1054 'V' => \&toggle_portable,
1055 'P' => \&callback_save_profile,
1056 );
1057 if (!$opt_in_place) {
1058 $command{'B'} = \&binary_menu if unix();
1059 $command{'C'} = \&collection_menu;
1060 $command{'S'} = \&scheme_menu;
1061 }
1062
1063 clear_screen;
1064 my $freestring = ($vars{'free_size'} >= 0 ? " (free: $vars{'free_size'} MB)" : "");
1065 print <<"EOF";
1066 ======================> TeX Live installation procedure <=====================
1067
1068 ======> Letters/digits in <angle brackets> indicate <=======
1069 ======> menu items for actions or customizations <=======
1070 = help> https://tug.org/texlive/doc/install-tl.html <=======
1071
1072 Detected platform: $this_platform
1073 $warn_nobin
1074 EOF
1075
1076 if (!$opt_in_place) {
1077 print <<"EOF";
1078 <B> set binary platforms: $vars{'n_systems_selected'} out of $vars{'n_systems_available'}
1079
1080 <S> set installation scheme: $vars{'selected_scheme'}
1081
1082 <C> set installation collections:
1083 $vars{'n_collections_selected'} collections out of $vars{'n_collections_available'}, disk space required: $vars{'total_size'} MB$freestring
1084 EOF
1085
1086 }
1087 if ($portable_toggled) {
1088 print $ptoggle_alert;
1089 $portable_toggled = 0;
1090 }
1091 print <<"EOF";
1092
1093 <D> set directories:
1094 TEXDIR (the main TeX directory):
1095 EOF
1096
1097 if (TeXLive::TLUtils::texdir_check($vars{'TEXDIR'}, 1)) {
1098 print " $vars{'TEXDIR'}\n";
1099 } else {
1100 print " !! default location: $vars{'TEXDIR'}\n";
1101 print " !! is not writable or not allowed, please select a different one!\n";
1102 }
1103 print <<"EOF";
1104 TEXMFLOCAL (directory for site-wide local files):
1105 $vars{'TEXMFLOCAL'}
1106 TEXMFSYSVAR (directory for variable and automatically generated data):
1107 $vars{'TEXMFSYSVAR'}
1108 TEXMFSYSCONFIG (directory for local config):
1109 $vars{'TEXMFSYSCONFIG'}
1110 TEXMFVAR (personal directory for variable and automatically generated data):
1111 $vars{'TEXMFVAR'}
1112 TEXMFCONFIG (personal directory for local config):
1113 $vars{'TEXMFCONFIG'}
1114 TEXMFHOME (directory for user-specific files):
1115 $vars{'TEXMFHOME'}
1116
1117 EOF
1118
1119 print <<"EOF";
1120 <O> options:
1121 $b_letter use letter size instead of A4 by default
1122 $b_restricted allow execution of restricted list of programs via \\write18
1123 $b_fmt create all format files
1124 EOF
1125
1126 if (!$opt_in_place) {
1127 if ($vars{'doc_splitting_supported'}) {
1128 print " $b_doc install macro/font doc tree\n";
1129 }
1130 if ($vars{'src_splitting_supported'}) {
1131 print " $b_src install macro/font source tree\n";
1132 }
1133 }
1134 if (wndws()) {
1135 if (!$vars{'instopt_portable'}) {
1136 print " $b_path adjust search path\n";
1137 print " $b_deskint add menu items, shortcuts, etc.\n";
1138 print " [$vars{'tlpdbopt_file_assocs'}] update file associations\n";
1139 if (admin()) {
1140 print " $b_admin make installation available to all users\n";
1141 }
1142 }
1143 print " $b_addoneditor install TeXworks front end\n";
1144 }
1145
1146 print " $b_path create symlinks to standard directories\n"
1147 unless ($vars{'instopt_portable'} || wndws());
1148
1149 print " $b_adjustrepo after install, set CTAN as source "
1150 . "for package updates\n"
1151 unless ($media eq 'NET');
1152
1153 if ($vars{'instopt_portable'}) {
1154 print "\n <V> set up for regular installation to hard disk\n";
1155 } else {
1156 print "\n <V> set up for portable installation\n";
1157 }
1158
1159 other_options qw(I P Q);
1160 my $answer = prompt 'Enter command';
1161
1162 if (defined $command{"\u$answer"}) {
1163 return $command{"\u$answer"};
1164 } else {
1165 print "Unknown command: $answer\n\n";
1166 return $command{'self'};
1167 }
1168 }
1169 # needs a terminal 1 for require to succeed!
1170 1;
1171
1172 __END__
1173
1174 ### Local Variables:
1175 ### perl-indent-level: 2
1176 ### tab-width: 2
1177 ### indent-tabs-mode: nil
1178 ### End:
1179 # vim:set tabstop=2 expandtab: #