From 3db1283a16caf97a52a5a22be0e316cff48c83c9 Mon Sep 17 00:00:00 2001
From: Yorhel
+ Indexing %s versions of %s manual pages found in
+ %s files of %s packages.
+
+ Manned.org aims to index all manual pages from a variety of systems, both
+ old and new, and provides a convenient interface for looking up and viewing
+ the various versions of each man page.
+ More information »
+
The state of online indices of manual pages used to be a sad one. Existing
sites used to only offer you a single version of a man page: From one
@@ -355,7 +354,7 @@ TUWF::get '/info/about' => sub {
harder to find a manual for a specific system. Additionally, some sites
rendered the manuals in an unreadable way, didn't correctly handle special
formatting - like tables - or didn't correctly display non-ASCII characters.
-
Nowadays there are many good alternatives, but Manned.org was one of the
sites created in order to improve that situation. This site aims to index
the manual pages from a variaty of systems, both old and new, and allows you
@@ -363,14 +362,14 @@ TUWF::get '/info/about' => sub {
system behaves. The manuals are stored in the database as UTF-8, and are
passed through groff to
render them in (mostly) the same way as they are displayed in your terminal.
-
This website is open
- source (MIT licensed) and written in a combination of Perl and Rust. The
- entire PostgreSQL database is available for download (see "Database
- download" below).
+ source (MIT licensed) and written in a combination of Perl and Rust.
+ The entire PostgreSQL database is available
+ for download.
You can link to specific packages and man pages with several URL formats.
These URLs will keep working in the future, so you should not have to worry
about eventual dead links.
- Manned.org aims to index all manual pages from a variety of systems, both
- old and new, and provides a convenient interface for looking up and viewing
- the various versions of each man page.
- About manned.org »
- _
- };
+ framework_ title => 'Man Pages Archive', mainclass => 'thin', sub {
+ h1_ 'Welcome to Manned.org';
+ h2_ 'The archive for man pages';
+ lit sprintf <<' _', map num($stats->{$_}), qw|hashes mans files packages|;
+ Goal
+ lit <<' _';
+ Goal
+
+ URL format
+ URL format
All man pages are fetched right from the (binary) packages available on the
public repositories of Linux distributions. In particular:
@@ -491,7 +490,7 @@ TUWF::get '/info/about' => sub {
The repositories are scanned for new packages on a daily basis.
This site is backed by a PostgreSQL database containing all the man pages. Weekly dumps of the full database are available for download at @@ -508,7 +507,7 @@ TUWF::get '/info/about' => sub { major version bumps may occur.
-
Suggestions for new (or old) systems to index are welcome.
@@ -524,7 +523,7 @@ TUWF::get '/info/about' => sub {
here. :-(
This site isn't nearly as awesome yet as it could be. Here's some ideas that would be nice to have in the future: @@ -538,7 +537,7 @@ TUWF::get '/info/about' => sub {
-All manual pages are copyrighted by their respective authors. The manuals have been fetched from publically available repositories of free and @@ -549,7 +548,7 @@ TUWF::get '/info/about' => sub { know and I will have it removed as soon as possible.
_ - } } + }; }; @@ -576,20 +575,19 @@ TUWF::get '/browse/search' => sub { my $man = search_man $q, 150; return tuwf->resRedirect("/$man->[0]{name}.$man->[0]{section}", 'temp') if @$man == 1; - framework_ title => 'Search results for '.$q, sub { + framework_ title => 'Search results for '.$q, mainclass => 'searchres', sub { h1_ 'Search results for '.$q; # Package search would also be useful. p_ 'Note: This is just a simple case-insensitive prefix match on the man names. In the future we\'ll have more powerful search functionality. Hopefully.'; if(@$man) { - ul_ id => 'searchres', sub { + ul_ sub { li_ sub { a_ href => "/$_->{name}.$_->{section}", $_->{name}; - i_ " $_->{section}"; + small_ " $_->{section}"; } for @$man; } } else { - br_; br_; - b_ 'No results :-('; + p_ 'No results :-('; } }; }; @@ -785,31 +783,32 @@ TUWF::get qr{/pkg/([^/]+)} => sub { $f->{c} ne 'all' ? ('AND LOWER(SUBSTR(name, 1, 1)) =', \$f->{c}) : (); my $count = tuwf->dbVali('SELECT count(*) FROM', $packages_with_man, 'p WHERE', $where); my $pkg = tuwf->dbPagei({ results => 200, page => $f->{p} }, - 'SELECT id, system, name, category FROM', $packages_with_man, 'p WHERE', $where, 'ORDER BY name' + 'SELECT id, system, name, category FROM', $packages_with_man, 'p WHERE', $where, 'ORDER BY name, category' ); - my $title = "Packages for $sys->{name}".($sys->{release}?" $sys->{release}":""); - framework_ title => $title, sub { - div_ id => 'pkglist', sub { - h1_ $title; - - p_ class => 'charselect', sub { + my $title = $sys->{name}.($sys->{release}?" $sys->{release}":""); + framework_ title => $title, mainclass => 'pkglist', sub { + div_ sub { + div_ sub { + h1_ $title; + }; + nav_ class => 'charselect', sub { for('all', 0, 'a'..'z') { a_ href => "/pkg/$short?c=$_", $_?uc$_:'#' if $_ ne $f->{c}; b_ $_?uc$_:'#' if $_ eq $f->{c}; } }; + }; + small_ '(Packages without man pages are not listed)'; - p_ 'Note: Packages without man pages are not listed.'; - paginate_ "/pkg/$short?c=$f->{c};p=", $count, 200, $f->{p}; - ul_ id => 'packages', sub { - li_ sub { - a_ href => "/pkg/$short/$_->{category}/$_->{name}", $_->{name}; - i_ ' '.$_->{category}; - } for @$pkg; - }; - paginate_ "/pkg/$short?c=$f->{c};p=", $count, 200, $f->{p}; - } + paginate_ "/pkg/$short?c=$f->{c};p=", $count, 200, $f->{p}; + ul_ sub { + li_ sub { + a_ href => "/pkg/$short/$_->{category}/$_->{name}", $_->{name}; + small_ ' '.$_->{category}; + } for @$pkg; + }; + paginate_ "/pkg/$short?c=$f->{c};p=", $count, 200, $f->{p}; }; }; @@ -846,33 +845,39 @@ TUWF::get qr{/pkg/([^/]+)/(.+)} => sub { # Latest version of this package determines last modification date of the page. tuwf->resLastMod($vers->[0]{released}); - my $title = "$sys->{name}".($sys->{release}?" $sys->{release}":"")." / $pkg->{category} / $pkg->{name}"; - framework_ title => "$title $sel->{version}", sub { - h1_ $title; - - div_ id => 'pkgversions', sub { - h2_ 'Versions'; - ul_ sub { - li_ sub { - a_ href => "/pkg/$sys->{short}/$pkg->{category}/$pkg->{name}/$_->{version}", $_->{version} if $_ != $sel; - b_ " $_->{version}" if $_ == $sel; - i_ " $_->{released}"; - } for(@$vers); - } + my $sysname = $sys->{name}.($sys->{release}?" $sys->{release}":""); + my $subtitle = " / $pkg->{category} / $pkg->{name}"; + framework_ title => "$sysname$subtitle $sel->{version}", mainclass => 'pkgpage', sub { + h1_ sub { + a_ href => "/pkg/$sys->{short}", $sysname; + txt_ $subtitle; }; - div_ id => 'pkgmans', sub { - h2_ "Manuals for version $sel->{version}"; - paginate_ "/pkg/$sys->{short}/$pkg->{category}/$pkg->{name}/$sel->{version}?p=", $count, 200, $p; - ul_ sub { - li_ sub { - a_ href => "/$_->{name}/".substr($_->{hash},0,8), "$_->{name}($_->{section})"; - b_ " $_->{locale}" if $_->{locale}; - i_ " $_->{filename}"; - } for(@$mans); + div_ sub { + section_ sub { + h2_ 'Versions'; + ul_ sub { + li_ sub { + a_ href => "/pkg/$sys->{short}/$pkg->{category}/$pkg->{name}/$_->{version}", $_->{version} if $_ != $sel; + b_ " $_->{version}" if $_ == $sel; + small_ " $_->{released}"; + } for(@$vers); + } }; - paginate_ "/pkg/$sys->{short}/$pkg->{category}/$pkg->{name}/$sel->{version}?p=", $count, 200, $p; - } + + section_ sub { + h2_ "Manuals for version $sel->{version}"; + paginate_ "/pkg/$sys->{short}/$pkg->{category}/$pkg->{name}/$sel->{version}?p=", $count, 200, $p; + ul_ sub { + li_ sub { + a_ href => "/$_->{name}/".substr($_->{hash},0,8), "$_->{name}($_->{section})"; + b_ " $_->{locale}" if $_->{locale}; + small_ " $_->{filename}"; + } for(@$mans); + }; + paginate_ "/pkg/$sys->{short}/$pkg->{category}/$pkg->{name}/$sel->{version}?p=", $count, 200, $p; + }; + }; } }; diff --git a/www/man.css b/www/man.css index 1a2cecb..c761a7d 100644 --- a/www/man.css +++ b/www/man.css @@ -1,85 +1,54 @@ -/* TODO: column-width is better done in Perl? (More like a column-count, then) */ - -* { margin: 0; padding: 0; font-family: "Trebuchet MS", sans-serif; } -html { background: #333; padding: 0 10px; } -body { margin: 10px auto 50px auto; max-width: 1100px; border-collapse: separate; padding-bottom: 10px; border-radius: 10px; box-shadow: 0 10px 10px #def; } -h1 { font-size: 24px; font-weight: normal; color: #abc; } -h2 { font-size: 21px; margin-top: 40px; color: #468; font-weight: normal; clear: left } -h2 + i { font-size: 12px; } -h3 { font-size: 16px; margin-top: 20px; color: #468; font-weight: normal } -a { color: #048; } +* { margin: 0; padding: 0; font-size: inherit; font-family: "Trebuchet MS", sans-serif; } +html { background: #fff; padding: 0 10px; color: #000 } +body { margin: 10px auto 50px auto; max-width: 1100px; border-collapse: separate; padding-bottom: 10px } +h1 { font-size: 24px; font-weight: normal } +h2 { font-size: 21px; margin-top: 35px; margin-bottom: 7px; font-weight: normal; border-bottom: 1px solid #ccc } +h3 { font-size: 18px; margin-top: 20px; margin-bottom: 5px; font-weight: normal } +a { color: #048; text-decoration: none } a:hover { text-decoration: underline; color: #48B;} -code { font-family: "Lucida Console", Monospace; font-size: 12px; background-color: #f0f8ff } +p { margin-bottom: 15px } +dl { margin-bottom: 15px } +dt { margin: 0 0 5px 0 } +dd { margin: 0 0 10px 10px; } +ul { margin: 0 0 15px 20px } +input { font-size: 0.9em; padding: 1px 2px } +code { font-family: "Lucida Console", Monospace; font-size: 12px; background-color: #f0f8ff; padding: 1px } +small { color: #aaa } .hidden { display: none!important; } -#header { padding: 4px 20px; border-bottom: 1px solid #888; font: 24px "Arial"; background: url('images/gradients.png') repeat-x; border-radius: 8px 8px 0 0; } -#header a { color: #f8f8f8; text-decoration: none; font-weight: bold; } -#header a:hover { background: none; } -#header form { float: right; } -#header input[type=text] { color: #000; width: 260px; padding: 1px 2px 1px 15px; border-radius: 12px 0 0 12px; border: 1px solid #444; - box-shadow: 1px 1px 3px #fff, -1px -1px 2px #234; background: url('images/gradients.png') 0 -105px repeat-x; height: 15px; } -#header input[type=text]:hover, #header input[type=text]:focus { background: url('images/gradients.png') 0 -122px repeat-x; outline: none; } -#header input[type=submit] { height: 23px; width: 62px; background-image: url('images/search.png'); border: 0; margin: 0 0 0 -5px; cursor: pointer } +header { border-bottom: 3px dotted #ccc; display: flex; justify-content: space-between; align-items: end; flex-wrap: wrap } +header a { font: 24px "Arial", serif; font-weight: bold } +header form { padding-bottom: 3px } +header input[type=text] { width: 100px } -#body { padding: 10px 10px 20px 10px; background: #fff } +footer { border-top: 3px dotted #ccc; color: #666; font-size: 12px; display: flex; justify-content: space-between; flex-wrap: wrap } -#systems a, -.charselect a, -.paginate a { color: #048; font-family: "Verdana"; font-weight: normal; text-decoration: none; padding: 3px 5px; border-radius: 4px; } +main { padding: 10px 0 25px 0 } +main.thin { max-width: 700px; margin: 0 auto } -.charselect b, -.paginate b { font-family: "Verdana"; padding: 3px } +.systems > div { margin: 25px 0; display: flex; align-items: start } +.systems > div > a { display: flex; align-items: center } +.systems img { width: 50px; height: 50px; margin-right: 10px } +.systems b { font-size: 24px; display: block } +.systems > div > div > a { padding-right: 10px } -#systems a:hover, -.charselect a:hover, -.paginate a:hover { background: #cde; } +.searchres ul { margin: 20px 0; list-style-type: none; column-width: 300px } +.searchres a { padding-right: 2px } -p.txt { margin: 5px 0 0 10px; max-width: 700px } -#external { list-style-type: none; margin-left: 10px } +.charselect a, .paginate a { display: inline-block; padding: 3px 5px } +.charselect b, .paginate b { display: inline-block; padding: 3px 5px } -i.grayedout { color: #aaa; font-size: 13px; } +.pkglist > div { display: flex; align-items: start; justify-content: space-between; flex-wrap: wrap } +.pkglist .paginate { margin: 10px 0; text-align: center } +.pkglist ul { margin: 20px 0; list-style-type: none; column-width: 300px } +.pkglist ul a { padding-right: 2px } -#about { max-width: 700px } -#about h2 { margin-bottom: 5px } -#about dl { margin-bottom: 5px } -#about dt { margin: 5px 0 0 10px } -#about p { margin: 0 0 0 10px; } -#about dd { margin: 0 0 0 20px; } -#about ul { padding: 5px 0 5px 30px } +.pkgpage > div { display: flex; flex-wrap: wrap; margin-top: 15px } +.pkgpage h2 { border-bottom: 0; margin: 0 0 10px 0 } +.pkgpage ul { margin: 0; list-style-type: none } +.pkgpage section:first-child { border-right: 1px dashed #468; padding: 0 10px } +.pkgpage section:last-child { padding: 0 10px } -#systems li { display: block; float: left; width: 300px; min-height: 80px; margin: 15px 10px; padding-left: 60px } -#systems span { display: block; margin-left: -55px; float: left; width: 50px; height: 50px; background-repeat: no-repeat; } -#systems a span { margin-top: 10px } -#systems b { font-size: 24px; display: block } - -#pkglist .charselect { float: right } -#pkglist .paginate { display: block; margin: 10px; width: 100%; text-align: center } - -#packages { margin: 20px 0; -webkit-column-width: 300px; -moz-column-width: 300px; column-width: 300px } -#packages li { display: block; } -#packages i { color: #aaa; font-size: 13px; } -#packages a { padding-right: 2px } - -#searchres { margin: 20px 0; -webkit-column-width: 300px; -moz-column-width: 300px; column-width: 300px } -#searchres li { display: block; } -#searchres i { color: #aaa; font-size: 13px; } -#searchres a { padding-right: 2px } - -#pkgversions { margin-top: 10px } -#pkgversions h2 { margin: 0 } -#pkgversions { float: left; padding: 0 10px; } -#pkgversions ul { margin: 10px 0; padding-right: 10px; border-right: 1px dashed #468 } -#pkgversions li { display: block; } -#pkgversions i { color: #aaa; font-size: 13px; } -#pkgversions a { padding-right: 2px } - -#pkgmans { margin-top: 10px } -#pkgmans h2 { margin: 0 } -#pkgmans { float: left } -#pkgmans .paginate { margin: 10px 0 } -#pkgmans ul { margin: 10px 0 } -#pkgmans li { display: block } -#pkgmans i { color: #aaa; font-size: 13px; } #manbuttons h1 { display: inline; margin: 0 20px 0 0; vertical-align: middle } #manbuttons ul { list-style-type: none; display: inline-block } @@ -92,7 +61,7 @@ i.grayedout { color: #aaa; font-size: 13px; } #manres { margin: 0 0 10px 0; width: 70%; padding: 10px; box-sizing: border-box; background: #f0f8ff; border-radius: 10px; border-left: 1px dashed #333; border-right: 1px dashed #333 } #manres i { color: #aaa; font-size: 13px; margin-left: 7px } -#manres ul { list-style-type: none } +#manres ul { list-style-type: none; margin-bottom: 0 } #manres ul a { outline: none; text-decoration: none } #manres ul .oldver a { color: #aaa; font-size: 13px } #manres div > ul { margin-top: 5px } /* System names */ @@ -117,11 +86,6 @@ i.grayedout { color: #aaa; font-size: 13px; } #contents { margin: 10px 0 0 0 } -#footer { height: 60px; clear: both; padding: 4px 10px; color: #f8f8f8; margin: 0 0 -20px 0; - border-top: 1px solid #888; font-size: 13px; background: url('images/gradients.png') 0 -37px repeat-x; border-radius: 0 0 8px 8px; } -#footer a { font-size: 13px; padding: 0; color: #f8f8f8; } -#footer a:hover { background: none; } - pre, pre * { font-family: "Lucida Console", Monospace; font-size: 15px } pre b, pre em, pre a { color: #369; font-weight: normal; text-decoration: none } pre em { font-style: italic } diff --git a/www/man.js b/www/man.js index 66b5efc..6e22b4b 100644 --- a/www/man.js +++ b/www/man.js @@ -459,24 +459,3 @@ function dsResults(hr, obj) { 'locations'))); })(); })(); - - - - -// The "more..." links on the homepage. -(function(){ - var sys = byId('systems'); - if(!sys) - return; - var f = function() { - var l = byName(this.parentNode, 'a'); - var show = hasClass(l[3], 'hidden'); - for(var i=3; i