summaryrefslogtreecommitdiff
path: root/Master/tlpkg/bin/tl-update-docindex
blob: 69a39571125c319ca870b9560fa1310aa9a75c10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#!/usr/bin/env perl
# $Id$
# Make index file of all HTML and PDF documentation (printed on stdout).
# Originally written 2009, Manuel P\'egouri\'e-Gonnard. WTFPL v2.

BEGIN {
    $0 =~ m#(.*)/(.*)#; ($progdir, $progname) = ($1, $2);
    unshift @INC, "$progdir/..";
}

use warnings FATAL => 'all';
use Fatal qw(:void open close opendir closedir chdir mkdir);

use TeXLive::TLPDB;
use File::Basename;

my $CATALOGUE_DIR = "/home/httpd/html/catalogue/entries";

exit(main());


sub main {
  my $tlpdb = TeXLive::TLPDB->new('root' => "$progdir/../..");
  die "$progname: unable to load TLPDB\n" unless defined $tlpdb;

  print <<END_HEADER;
<html><head>
<title>TeX Live documentation</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<style type="text/css"> ol { padding-left: 4em } </style>
</head><body>
<h1>TeX Live documentation</h1>

<p>This document lists links to all HTML and PDF files for packages and guides
contained in <a href="https://tug.org/texlive/">TeX Live</a> (<a
href="https://tug.org/texlive/doc.html">TL documentation web page),
sorted by package name.</p>

<p>For documentation on TeX Live itself, see the <a
href="#texlive-en">texlive-en</a> package below and its several nearby
translations, as well as the <a href="#texlive.infra">texlive.infra</a>
and <a href="#texlive-scripts">texlive-scripts</a> packages. There are
also links from the <a href=".">index.html</a> page here.
END_HEADER

  print_all_pkg($tlpdb);

  # print footer
  chomp (my $date = `LC_ALL=C date`);
  print <<END_TRAILER;
<hr>
<small>Generated $date by $progname.</small>
</body></html>
END_TRAILER

  return 0;
}


# print the links for letters, then packages
#
sub print_all_pkg {
  my ($tlpdb) = @_;

  # @lines is the big list, @letters the list of initials of package names
  local (@lines, @letters, $current_letter, $n);
  $current_letter = "\0";

  # first build the output and the list of initials
  for my $tlpn (sort {lc $a cmp lc $b} $tlpdb->list_packages) {
    # don't show our infra packages, just confusing:
    next if $tlpn =~ /^00texlive\.|texlive-docindex/;
    my $tlpkg = $tlpdb->get_package($tlpn);
    push_pkg_list($tlpkg);
  }
  push @lines, "\n</ol>\n\n";

  # then actually print them
  my $access = "\n<p>" . join(" - ", @letters) . "</p>\n";
  print $access;
  print @lines;
  print $access;
}


# push the content for a package to the list of lines
#
sub push_pkg_list {
  my ($tlpkg) = @_;
  my $name = $tlpkg->name;
  my @docfiles = $tlpkg->docfiles;

  # almost always the documentation is in doc, where it should be.
  @docfiles = grep { m/\.(html|pdf)/ } @docfiles;
  if (@docfiles == 0) {
    # but in one notable case, koma-script, it is in runfiles,
    # per the author's specification.
    my @runfiles = $tlpkg->runfiles;
    @docfiles = grep { m/\.(html|pdf)/ } @runfiles;
  }

  # if no adequate documentation is found, print nothing
  return if @docfiles == 0;
  $n++; # list counter

  # check initial
  my $init = uc(substr($name, 0, 1));
  unless ($init eq $current_letter) {
    $current_letter = $init;
    # put header in the big list...
    push @lines, "\n</ol>\n" unless $n == 1;
    push @lines, qq#\n<h2 id="letter-$init">$init</h2>\n#;
    push @lines, qq#\n<ol start="$n">\n#;
    # ... and a reference in quick access list
    push @letters, qq!<a href="#letter-$init">$init</a>!;
  }

  # if there is an index.html file, drop the rest
  # catches, e.g.: FAQ-en bosisio epspdf fontname jadetex
  # metapost ppower4 sttools tds tex4ht
  my @index = grep /\/index\.html/, @docfiles;
  if (@index == 1) {
    #warn "Using index.html for $name\n";
    @docfiles = @index;
  }

  # print package name with ctan link and shortdesc
  my $id = qq!id="$name"!; # should be unique
  my $dir = &find_doc_dir($name, @docfiles);
  push @lines, qq#\n<li $id><b><a href="$dir/">$name</a></b><small>\n#;
  #
  # Don't link to CTAN if the package doesn't exist.
  # We could find more by looking at the .tlpsrc, but let's skip
  # until someone notices. Except 12many works, and it's the very
  # first one, so add that in.
  my $lc_name = lc($name);
  my $name1 = substr($name, 0, 1); # for Catalogue check
  push @lines, qq#(<a href="https://ctan.org/pkg/$name">CTAN</a>):\n#
    if -r "$CATALOGUE_DIR/$name1/$lc_name.xml" || $name eq "12many";
  #
  my $shortdesc = $tlpkg->shortdesc;
  # a few shortdescs already end with a period:
  $shortdesc =~ s/\.$// if defined $shortdesc;
  push @lines, "$shortdesc.&nbsp;\n" if defined $shortdesc;
  #warn "$name\n" if not defined $shortdesc;

  # now the list of docfiles
  my $list;
  for my $file (@docfiles) {
    my $name = basename($file);
    $list .= qq#<a href="$file">$name</a>#;
    my $dflanguage = $tlpkg->{'docfiledata'}{$file}{'language'};
    $list .= "&nbsp;($dflanguage)&nbsp;"
             if (defined $dflanguage && $dflanguage ne "en");
    $list .= "\n";
  }
  $list =~ s/(&nbsp;)?\n$//;
  push @lines, "$list\n</small></li>\n";
}


# Return best documentation directory for package NAME among @DOCFILES.
# 
sub find_doc_dir {
  my ($name,@docfiles) = @_;

  my $shortest_dir = "a" x 1000;
  my $name_dir = "";
  for my $f (@docfiles) {
    next if $f eq "doc.html"; # top-level doc.html is just confusing
    my $dir = dirname($f);
    
    # if we find a file in a directory named for the package,
    # that seems like the best possible choice.
    if ($dir =~ m,/$name$,) {
      return $dir;

    # if we are in the $name/base/ directory, e.g., amstex/base.
    } elsif ($dir =~ m,/$name/base$,) {
      return $dir;

    # else if we are one directory from the package name,
    # e.g., authorarchive/examples, can probably use it.
    } elsif ($dir =~ m,/$name/[^/]+$,) {
      $name_dir = dirname($dir);
      
    # otherwise, shorter is probably better.
    } elsif (length($dir) < length($shortest_dir)) {
      $shortest_dir = $dir;
      ; #warn "set shortest $shortest_dir from $f for $name\n";
    } else {
      ; #warn "have $shortest_dir, ignoring $dir from $f\n";
    }
  }

  # a directory by name is probably better than just the shortest.
  return $name_dir if $name_dir;
  
  if ($shortest_dir !~ m,/,) {
    # should never happen except for texlive.infra, which has the
    # top-level index.html.
    warn "no shortest dir for $name, should never happen! docfiles=@docfiles"
      unless $name eq "texlive.infra";
    return "";
  } else {
    ; #warn "returning shortest $shortest_dir for $name\n";
    return $shortest_dir;
  }
}