diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2014-09-13 09:43:21 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2014-09-13 09:43:21 -0700 |
commit | 5280f9a0cd1f9ba200422ebba65d1e0133410995 (patch) | |
tree | bf85ce4e320a769d7e0903ff52ccfde13a422666 /misc | |
download | man-1.6g.tar.gz man-1.6g.tar.bz2 man-1.6g.zip |
Initial.man-1.6g
Diffstat (limited to 'misc')
-rw-r--r-- | misc/README | 4 | ||||
-rw-r--r-- | misc/locales/it/manlint.1 | 66 | ||||
-rw-r--r-- | misc/man-preformat.c | 332 | ||||
-rw-r--r-- | misc/manlint | 225 | ||||
-rw-r--r-- | misc/manlint.1 | 63 |
5 files changed, 690 insertions, 0 deletions
diff --git a/misc/README b/misc/README new file mode 100644 index 0000000..5d20cf1 --- /dev/null +++ b/misc/README @@ -0,0 +1,4 @@ +Here a contributed program to preformat man pages. Untested. +Comments, suggestions and patches are welcome. + +flc, <flucifredi@acm.org>. diff --git a/misc/locales/it/manlint.1 b/misc/locales/it/manlint.1 new file mode 100644 index 0000000..11aac7e --- /dev/null +++ b/misc/locales/it/manlint.1 @@ -0,0 +1,66 @@ +'\"
+.\" (C) Copyright 1999 David A. Wheeler (dwheeler@ida.org)
+.\"
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one
+.\"
+.\" Since the Linux kernel and libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date. The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein. The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\"
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\"
+.\" Modified Wed Jul 14 23:00:00 1999 by David A. Wheeler (dwheeler@ida.org)
+.\"
+.\" Traduzione da man-1.6d di Giulio Daprelā <giulio@pluto.it>
+.\" Revisione a cura di Vieri Giugni <v.giugni@gmail.com>
+.\" giugno 2006
+.\"
+.TH MANLINT 1 "14 luglio 1999" "Linux" "Linux Programmer's Manual"
+.SH NOME
+manlint \- programma per identificare errori di formattazione in pagine man o mdoc
+.SH SINTASSI
+.BR manlint " [ " options " ] [ " "list of files" " ] "
+.SH DESCRIZIONE
+manlint
+č un programma che identifica lint (errori) nella formattazione di pagine
+man o mdoc page, in modo simile a quello di un controllo ortografico per un testo
+ordinario. Manlint ha un elenco di macro e sequenze di escape ammesse,
+e segnala l'uso di qualunque macro o sequenza di escape che non sia
+nell'elenco di riferimento.
+Questo elenco di riferimento include tutte le macro definite in
+.BR man (7),
+.BR mdoc (7),
+e un sottoinsieme sicuro di troff definito in
+.BR man (7).
+manlint inoltre verifica la conformitā alle varie regole.
+.PP
+Se una man page supera la verifica di manlint, dovrebbe risultare
+ampiamente portabile, anche con strumenti come
+.BR man2html (1)
+che non implementano completamente troff.
+.PP
+Se non viene indicato un elenco di file, viene letto lo standard input.
+Un file con il nome "-" viene interpretato come standard input.
+.SH BUG
+Attualmente il programma č alquanto incompleto.
+Non ha nessuna opzione, non verifica le sequenze di escape,
+e non č in grado di gestire il formato mdoc.
+Inoltre, č chiaro cosa deve fare, e anche nella sua forma attuale
+puō trovare tantissimi problemi nei file man esistenti.
+.SH AUTORE
+David A. Wheeler (dwheeler@ida.org)
+.SH "VEDERE ANCHE"
+.BR man (7),
+.BR mdoc (7).
diff --git a/misc/man-preformat.c b/misc/man-preformat.c new file mode 100644 index 0000000..79f4d45 --- /dev/null +++ b/misc/man-preformat.c @@ -0,0 +1,332 @@ +From bryanh@giraffe.giraffe.netgate.net Sat Nov 16 09:32:59 1996 +Received: from giraffe.giraffe.netgate.net by hera.cwi.nl with SMTP + id <AA24735@cwi.nl>; Sat, 16 Nov 1996 09:32:53 +0100 +Received: (from bryanh@localhost) by giraffe.giraffe.netgate.net (8.6.11/8.6.9) id AAA00639; Sat, 16 Nov 1996 00:32:46 -0800 +Date: Sat, 16 Nov 1996 00:32:46 -0800 +Message-Id: <199611160832.AAA00639@giraffe.giraffe.netgate.net> +From: bryanh@giraffe.netgate.net (Bryan Henderson) +To: Andries.Brouwer@cwi.nl +In-Reply-To: <9611151043.AA01606=aeb@zeus.cwi.nl> (Andries.Brouwer@cwi.nl) +Subject: Re: cross references for Linux man page package +Status: RO + +>I hope a shell script or perl script? + +Well, no. Shell scripts are too hard and I don't know perl. So it's in +tortured C. It also needs the shhopt package (from sunsite), which +effortlessly parses a command line, but not many people know about it. +So maybe this isn't up to distributions standards. + + +Here it is anyway. You invoke it just like this: + + preformat ls.1 + +Or for a whole directory, + + preformat * + +Or if you keep preformatted man pages elsewhere than /usr/man/preformat/catN, + + preformat --mandir=/usr/local/doc/package_xyz/man * + +It makes the target directories where necessary and groffs and gzips the +man pages into them. If it finds a man page that looks like ".so whatever", +it just does a symbolic link to the base file instead. + +-------------------------------------------------------------------------- +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <shhopt.h> + +#define TRUE 1 +#define FALSE 0 + + + +void +compute_mkdir_command(const char *installed_path, + char *mkdir_cmd, const int mkdir_cmd_l) { +/*---------------------------------------------------------------------------- + Figure out what, if any, mkdir command we need to create the directories + in which to put the file whose full pathname is <installed_path>. +----------------------------------------------------------------------------*/ + char *slash_p; /* pointer to last slash in installed_path. */ + char need_dir[strlen(installed_path)+1]; + /* pathname of directory which must exist so we can install the man + page into it. If we're just defaulting to the current directory, + then this is a null string. + */ + + slash_p = strrchr(installed_path, '/'); + if (slash_p == NULL) need_dir[0] = '\0'; + else { + int need_dir_l; /* length for need_dir */ + need_dir_l = slash_p - installed_path + 1; /* includes slash */ + strncpy(need_dir, installed_path, need_dir_l); + need_dir[need_dir_l] = '\0'; /* need that string terminator */ + } + + if (need_dir[0] == '\0') + mkdir_cmd[0] = '\0'; + else { + struct stat stat_buf; /* results of a stat system call */ + int rc; /* return code from stat() */ + + rc = stat(need_dir, &stat_buf); + if (rc == 0) + mkdir_cmd[0] = '\0'; + else + sprintf(mkdir_cmd, "umask 002;mkdir --parents %s; ", need_dir); + } +} + + + +void +extract_dot_so_stmt(const char *man_page_source_path, + char *dot_so_stmt, const int dot_so_stmt_l) { + + FILE *source_file; + + source_file = fopen(man_page_source_path, "r"); + if (source_file != NULL) { + char buffer[200]; /* First line of file */ + + fgets(buffer, sizeof(buffer), source_file); + fclose(source_file); + + if (strncmp(buffer, ".so ", 4) == 0) + snprintf(dot_so_stmt, dot_so_stmt_l, "%s", buffer); + else dot_so_stmt[0] = '\0'; + } else dot_so_stmt[0] = '\0'; +} + + + +void +format_page(const char *installed_path, const char *man_page_source_path, + const char *mkdir_cmd, int *rc_p) { +/*---------------------------------------------------------------------------- + Format and compress the groff source in file <man_page_source_path> + and put the output in <installed_path>. Execute the possible mkdir + command <mkdir_cmd> too. +-----------------------------------------------------------------------------*/ + char shell_command[100+strlen(installed_path) + + strlen(man_page_source_path) + + strlen(mkdir_cmd)]; + /* A pipeline we have the shell execute */ + int rc; /* local return code */ + + snprintf(shell_command, sizeof(shell_command), + "%sgroff -Tlatin1 -mandoc %s | gzip >%s", + mkdir_cmd, man_page_source_path, installed_path); + + printf("%s\n", shell_command); + rc = system(shell_command); + if (rc != 0) { + fprintf(stderr, "groff pipeline failed, rc = %d\n", rc); + *rc_p = 10; + } else { + *rc_p = 0; + chmod(installed_path, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH + ); + } +} + + + +void +create_symlink(const char *installed_path, const char *dot_so_stmt, + const char *mkdir_cmd, int *rc_p) { +/*---------------------------------------------------------------------------- + Create a symlink from <installed_path> to the installed name of the man + page identified by <dot_so_stmt>. + + We make some large assumptions about the .so statement, so this may return + gibberish. + + Execute the possible mkdir command <mkdir_cmd> too. +-----------------------------------------------------------------------------*/ + char shell_command[100+strlen(mkdir_cmd) + + strlen(installed_path) + + strlen(dot_so_stmt)]; + /* A pipeline we have the shell execute */ + int rc; /* local return code */ + char *slash_p; /* pointer to last slash in .so statement, or NULL */ + + slash_p = strrchr(dot_so_stmt, '/'); + if (slash_p == NULL) { + fprintf(stderr, "Cannot find the base filename " + "in the .so statement '%s'. There is no slash ('/').\n", + dot_so_stmt); + *rc_p = 15; + } else if (*(slash_p+1) == '\0') { + fprintf(stderr, "Cannot find the base filename " + "in the .so statement '%s'. There is nothing after the " + "last slash ('/').", + dot_so_stmt); + *rc_p = 13; + } else { + char link_contents[200]; + + strncpy(link_contents, slash_p+1, sizeof(link_contents)-10); + if (link_contents[strlen(link_contents)-1] == '\n') + link_contents[strlen(link_contents)-1] = '\0'; + strcat(link_contents, ".gz"); + + sprintf(shell_command, "%sln --symbolic %s %s", + mkdir_cmd, link_contents, installed_path); + + printf("%s\n", shell_command); + rc = system(shell_command); + if (rc != 0) { + fprintf(stderr, "ln pipeline failed, rc = %d\n", rc); + *rc_p = 10; + } else *rc_p = 0; + } +} + + + +void +install_it(char *installed_path, char *man_page_source_path, int *rc_p){ +/*---------------------------------------------------------------------------- + Take the man page groff source in file <man_page_source_path>, format + it, compress it, and place it in file <installed_path>. + + Special case: If the file appears to be just a groff .so statement, + don't format it; instead, create a symbolic link that will do the same + thing as formatting the .so. A .so statement looks like: + + .so man3/basepage.3 + + and means to include all the groff source from the file man3/basepage.3. + So we just create a symbolic link to cat3/basepage.3.gz and save some + redundancy. + + + Make any directories necessary to create file <installed_path>. + +-----------------------------------------------------------------------------*/ + char mkdir_cmd[30 + strlen(installed_path)]; + /* A mkdir shell command to create the necessary directories. Null + string if no directory needs creating. + */ + char dot_so_stmt[200]; + /* The .so statement from the man page source, if the man page appears + to be one that consists solely of a .so statement. If it doesn't + appear so, this is an empty string. + */ + + /* We have to remove the file first, because it may be a symbolic link + for the purposes of having the same man page come up for multiple + commands. If we just overwrite, we will be replacing the base file, + which we don't want to do. + */ + unlink(installed_path); + + compute_mkdir_command(installed_path, mkdir_cmd, sizeof(mkdir_cmd)); + + extract_dot_so_stmt(man_page_source_path, dot_so_stmt, sizeof(dot_so_stmt)); + + if (*dot_so_stmt != '\0') + create_symlink(installed_path, dot_so_stmt, mkdir_cmd, rc_p); + else + format_page(installed_path, man_page_source_path, mkdir_cmd, rc_p); +} + + + +char * +just_filename(const char *full_path) { +/*---------------------------------------------------------------------------- + Return pointer into <full_path> of start of filename part. + Return NULL if pathname ends with a slash (i.e. it's a directory). +-----------------------------------------------------------------------------*/ + char *slash_p; /* Pointer to last slash in <full_path> */ + char *filename; /* Our eventual result */ + + slash_p = strrchr(full_path, '/'); + if (slash_p == NULL) filename = (char *) full_path; + else if (*(slash_p+1) == '\0') { + filename = NULL; + } else filename = slash_p+1; + return(filename); +} + + + +int main(int argc, char *argv[]) { + char *mandir; + /* The directory in which the formatted man pages are to go. This is + the parent directory of the cat1, cat2, etc. directories. + */ + char default_mandir[] = "/usr/man/preformat"; + /* default value for mandir, if user doesn't give --mandir option */ + int error; /* boolean: we've encountered an error */ + int i; /* local for loop index */ + + const optStruct option_def[] = { + { 0, (char *) "mandir", OPT_STRING, &mandir, 0}, + { 0, 0, OPT_END, 0, 0} + }; + int argc_parse; /* argc, except we modify it as we parse */ + char **argv_parse; /* argv, except we modify it as we parse */ + + mandir = default_mandir; /* initial assumption - default */ + argc_parse = argc; argv_parse = argv; + optParseOptions(&argc_parse, argv_parse, option_def, 0); + /* uses and sets argc_parse, argv_parse. */ + /* sets mandir (via option_def) */ + + error = FALSE; /* no error yet */ + + for (i=1;i <= argc_parse-1 && !error; i++) { + /* Do one of the man pages specified in the program arguments */ + char *man_page_source_path; + /* string: pathname of man page source file we're supposed to install + */ + char *man_page_source_fn; /* pointer within pathname to filename */ + char *dot_p; /* pointer within filename to last dot */ + + char man_section; /* man section number to which this page belongs */ + char installed_path[100]; /* full pathname for installed man page file */ + + man_page_source_path = argv_parse[i]; + + man_page_source_fn = just_filename(man_page_source_path); + if (man_page_source_fn == NULL) + fprintf(stderr, "Need filename at the end of pathname: %s\n", + man_page_source_path); + else { + dot_p = strrchr(man_page_source_fn, '.'); + if (dot_p == NULL) { + fprintf(stderr, "Invalid source file -- contains no period: %s\n", + man_page_source_fn); + } else if (*(dot_p+1) == '\0') { + fprintf(stderr, "Invalid source file -- need at least one character " + "after the last period: %s\n", man_page_source_fn); + } else { + int rc; /* local return code */ + /* Filename has a dot with at least one character after it. + Manual section number is the character right after that dot. + */ + man_section = *(dot_p+1); + + sprintf(installed_path, "%s/cat%c/%s.gz", + mandir, man_section, man_page_source_fn); + + install_it(installed_path, man_page_source_path, &rc); + if (rc != 0) error = TRUE; + } + } + } + return(error); +} + diff --git a/misc/manlint b/misc/manlint new file mode 100644 index 0000000..c919a94 --- /dev/null +++ b/misc/manlint @@ -0,0 +1,225 @@ +#!/usr/bin/perl -w + +# manlint - report "errors" in man page(s). + +# USAGE: +# manlint [list of files to check] +# +# EXAMPLE: +# manlint /usr/man/man*/*.* | less + +# An error is anything not known to be a safe construct in a man page; +# see man(7) for more information. +# Currently it's excessively paranoid, but that's the point -- this +# program assumes there's a problem, and if it isn't we can add that to the +# ruleset so that what's safe is explicitly spelled out. +# Currently this program only examines tmac.an based pages, the normal +# kind encountered in Linux. This is different than the BSD manddoc format, +# which is used by a number of man pages. + +# (C) 1999 David A. Wheeler (dwheeler@ida.org) + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +require 5.002; # Requires Perl 5.002 because functions are prototyped. + +# First, set up configuration. + +$debug = 0; +$errs = $totalerrs = 0; +$goodfiles = $badfiles = $skipfiles = 0; +$filename = ''; + +# Allow options for small or large safe set; just printing if a file fails +# instead of detail; auto-skip BSD files. + +# This is a list of "safe" macros, with their value being the +# maximum number of allowed parameters (-1 = any, 0=no parameters allowed) +%safemacros = ( + 'TH' => 5, + # Font Control: + 'B' => -1, 'BI' => -1, 'BR' => -1, + 'I' => -1, 'IB' => -1, 'IR' => -1, + 'RB' => -1, 'RI' => -1, 'SB' => -1, 'SM' => -1, + # tmac.an other macros: + 'SH' => 1, + 'LP' => 0, 'P' => 0, + 'PP' => 0, + 'RS' => 1, 'RE' => 0, + 'HP' => 1, 'IP' => 2, 'TP' => 1, + 'DT' => 0, 'PD' => 1, 'SS' => 1, + # We'll allow IX (indexing). + 'IX' => -1, + # I'm adding the UR, UN, and UE macros that will permit embedded URIs. + 'UR' => 1, + 'UN' => 1, + 'UE' => 0, + # allowed troff macros + '\\"' => -1, # troff comments + 'ps' => 1, # Point size + 'ft' => 1, # Font commands (not recommended, may be ignored in some cases) + 'hy' => 1, # Hyphenation (probably ignored in translation) + 'bp' => 0, # Force page break; optional parameter forbidden. + 'ne' => 1, # Need lines (likely to be ignored in translation) + 'br' => 0, + 'nf' => 0, # No-fill; insert breaks at end of each line. + 'fi' => 0, + 'ig' => 1, + '.' => 0, # standard end-of-ignore/end-of-definition. + 'ce' => 1, # Center next N lines + 'ad' => 1, + 'na' => 0, + # Will probably need to handle some if. + 'if' => -1, # LIMITED VERSION. + 'ie' => -1, # LIMITED VERSION. + 'el' => -1, + 'so' => 1, # Handle 'so' for shared man pages + 'sp' => 1, # Vertical Space - only permit positive values. + 'de' => 1, # Handling 'macro define' is a pain, but many pages require it. + 'ds' => -1, # Allow string defines. + 'in' => 1, # Require that every indent be paired with a negative indent. + 'ti' => 1, # Temporary indent may be ignored + 'hy' => 1, # Hypenation almost certainly ignored by anyone else. + 'nh' => 1, # Again, hyphenation likely ignored. + 'tr' => 1, # Translations limited, see below. +); + +# Allowed parameters for the ft (font) troff command. +%allowed_ft_parameter = ( + '1' => 1, + '2' => 1, + '3' => 1, + '4' => 1, + 'R' => 1, + 'I' => 1, + 'B' => 1, + 'P' => 1, + 'CW' => 1, + '' => 1, +); + +%allowed_tr = ( + '\\(ts"' => 1, + '\\(is\'' => 1, + '\\(if`' => 1, + '\\(pd"' => 1, + '\\(*W-|\(bv\*(Tr' => 1, + '\\*(Tr' => 1, +); + +sub problem($) { + # Report a problem, if you should. + my $message = shift; + print "${ARGV}: $message\n"; + $errs++; +} + +sub clean_state { + %defined_macros = (); + $is_skipped = 0; +} + +sub process_line { + # Process line already read in $_ (default input line). + my $macro; + my $parameters; + if (m/^[.']\s*([^\s]+)\s*(.*)?/) { + $macro=$1; + $parameters=$2; + $macro =~ s/\s//g; + print "Found macro: #${macro}#\n" if $debug; + if ($macro =~ m/Dd/) { # Is this the BSD macro set and not a tmac.an set? + problem("Uses BSD mandoc conventions instead of tmac.an"); + $errs--; # Patch up error count. + # print "${ARGV}: Uses BSD mandoc conventions instead of tmac.an.\n"; + close(ARGV); # Skip the rest of this file. + $is_skipped = 1; + return; + } + if ($macro =~ m/\\"/) {return;} # Skip troff comments. + if (exists($defined_macros{$macro})) { + return; # ??? Should examine the macro parameters. + } + if (exists($safemacros{$macro}) ) { + # ??? Check parameter count. + # ??? Check that .TH is the first macro (note: bash.1, etc., break this) + if ( ($macro eq 'if') || ($macro eq 'ie' )) { + # Only permit checking 't' or 'n' for now. + if ($parameters =~ m/^[tn]\s/) { + $_ = $parameters; + s/^[tn]\s+//; + process_line(); # Re-examine line without the if statement. + } else { + problem("unsafe use of if/ie"); + } + # ??? sp: only no-parameter or positive values. + } elsif ($macro eq 'de') { + $parameters =~ m/^([^\s]+)/; + $is_defining = $1; + $defined_macros{$is_defining} = 1; + } elsif ($macro eq 'so') { + $parameters =~ m/^([^\s]+)/; + $new_file = $1; + while (<$new_file>) { process_line(); } + } elsif (($macro eq 'ft') && (defined($parameters)) + && (! exists($allowed_ft_parameter{$parameters}))) { + problem("forbidden ft parameter $parameters"); + } elsif (($macro eq 'tr') && (defined($parameters)) + && (! exists($allowed_tr{$parameters}))) { + problem("forbidden tr parameter $parameters"); + } + # ??? 'in': Require that every indent be paired with a negative indent. + # ??? For macros with text after them, check their text's escapes. + } else { + problem("unsafe macro $macro"); + } + } else { + # ??? Regular text; check escape clauses. + } +} + + +# Main loop: Process files, looking for errors. + +clean_state(); + +while (<>) { + if ($ARGV ne $filename) { + print "Processing $ARGV; up to now good=$goodfiles bad=$badfiles skip=$skipfiles\n"; + $filename=$ARGV; + } + process_line(); +} continue { + if (eof) { # End of processing this file. + close ARGV; # Perl magic to get line #s to be accurate. + $totalerrs += $errs; + if ($errs) { $badfiles++ } else { + if ($is_skipped) {$skipfiles++} else {$goodfiles++}; + } + $errs = 0; + clean_state(); + } +} + +print "Number of good files = $goodfiles\n"; +print "Number of bad files = $badfiles\n"; +print "Number of skipped files = $skipfiles\n"; +exit $errs; + +# ??? Handle .so better (esp. the error messages) +# currently error messages don't report the traceback & they should. + + diff --git a/misc/manlint.1 b/misc/manlint.1 new file mode 100644 index 0000000..ab76009 --- /dev/null +++ b/misc/manlint.1 @@ -0,0 +1,63 @@ +'\" +.\" (C) Copyright 1999 David A. Wheeler (dwheeler@ida.org) +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of this +.\" manual under the conditions for verbatim copying, provided that the +.\" entire resulting derived work is distributed under the terms of a +.\" permission notice identical to this one +.\" +.\" Since the Linux kernel and libraries are constantly changing, this +.\" manual page may be incorrect or out-of-date. The author(s) assume no +.\" responsibility for errors or omissions, or for damages resulting from +.\" the use of the information contained herein. The author(s) may not +.\" have taken the same level of care in the production of this manual, +.\" which is licensed free of charge, as they might when working +.\" professionally. +.\" +.\" Formatted or processed versions of this manual, if unaccompanied by +.\" the source, must acknowledge the copyright and authors of this work. +.\" +.\" Modified Wed Jul 14 23:00:00 1999 by David A. Wheeler (dwheeler@ida.org) +.TH MANLINT 1 "14 July 1999" "Linux" "Linux Programmer's Manual" +.SH NAME +manlint \- program to report errors in man or mdoc pages +.SH SYNOPSIS +.BR manlint " [ " options " ] [ " "list of files" " ] " +.SH DESCRIPTION +manlint +is a program that identifies lint (errors) in man or mdoc page formatting, +similar to a spelling checker for ordinary text. +Manlint has a list of permitted macros and escape sequences, +and reports the use of any macro or escape sequence not in the +permitted list. +This permitted list includes all the macros defined in +.BR man (7), +.BR mdoc (7), +and the safe subset of troff defined in +.BR man (7). +manlint also checks for conformance to various rules. +.PP +If a man page passes manlint, it should be widely portable, even +to tools such as +.BR man2html (1) +which don't implement all of troff. +.PP +If a list of files is omitted, the standard input is used. +A file by the name "-" is interpreted as the standard input. +.SH BUGS +Currently the program is very incomplete. +It doesn't have any options, it doesn't actually check escape sequences, +and it can't handle mdoc format. +Still, it's clear what it should do, and even in its current form +it can find lots of problems in existing man files. +.SH AUTHOR +David A. Wheeler (dwheeler@ida.org) was the original author of +.BR "manlint" . +Federico Lucifredi <flucifredi@acm.org> is the current maintainer. +.SH "SEE ALSO" +.BR man (7), +.BR mdoc (7). |