mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
added ffplay documentation - added automatic man page generation for ffmpeg, ffserver and ffplay
Originally committed as revision 2136 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
d6eb3c500a
commit
e99c4e1037
11
doc/Makefile
11
doc/Makefile
@ -1,7 +1,14 @@
|
||||
all: ffmpeg-doc.html faq.html ffserver-doc.html hooks.html
|
||||
all: ffmpeg-doc.html faq.html ffserver-doc.html ffplay-doc.html hooks.html \
|
||||
ffmpeg.1 ffserver.1 ffplay.1
|
||||
|
||||
%.html: %.texi Makefile
|
||||
texi2html -monolithic -number $<
|
||||
|
||||
%.pod: %-doc.texi
|
||||
./texi2pod.pl $< $@
|
||||
|
||||
%.1: %.pod
|
||||
pod2man --section=1 --center=" " --release=" " $< > $@
|
||||
|
||||
clean:
|
||||
rm -f *.html
|
||||
rm -f *.html *.pod *.1
|
||||
|
@ -22,19 +22,21 @@ video on the fly with a high quality polyphase filter.
|
||||
|
||||
@chapter Quick Start
|
||||
|
||||
@c man begin EXAMPLES
|
||||
@section Video and Audio grabbing
|
||||
|
||||
FFmpeg can use a video4linux compatible video source and any Open Sound
|
||||
System audio source:
|
||||
FFmpeg can use a video4linux compatible video source and any Open Sound
|
||||
System audio source:
|
||||
|
||||
@example
|
||||
ffmpeg /tmp/out.mpg
|
||||
ffmpeg /tmp/out.mpg
|
||||
@end example
|
||||
|
||||
Note that you must activate the right video source and channel before
|
||||
launching ffmpeg. You can use any TV viewer such as xawtv
|
||||
(@url{http://bytesex.org/xawtv/}) by Gerd Knorr which I find very
|
||||
good. You must also set correctly the audio recording levels with a
|
||||
standard mixer.
|
||||
Note that you must activate the right video source and channel before
|
||||
launching ffmpeg. You can use any TV viewer such as xawtv
|
||||
(@url{http://bytesex.org/xawtv/}) by Gerd Knorr which I find very
|
||||
good. You must also set correctly the audio recording levels with a
|
||||
standard mixer.
|
||||
|
||||
@section Video and Audio file format conversion
|
||||
|
||||
@ -45,108 +47,114 @@ Examples:
|
||||
* You can input from YUV files:
|
||||
|
||||
@example
|
||||
ffmpeg -i /tmp/test%d.Y /tmp/out.mpg
|
||||
ffmpeg -i /tmp/test%d.Y /tmp/out.mpg
|
||||
@end example
|
||||
|
||||
It will use the files:
|
||||
It will use the files:
|
||||
@example
|
||||
/tmp/test0.Y, /tmp/test0.U, /tmp/test0.V,
|
||||
/tmp/test1.Y, /tmp/test1.U, /tmp/test1.V, etc...
|
||||
/tmp/test0.Y, /tmp/test0.U, /tmp/test0.V,
|
||||
/tmp/test1.Y, /tmp/test1.U, /tmp/test1.V, etc...
|
||||
@end example
|
||||
|
||||
The Y files use twice the resolution of the U and V files. They are
|
||||
raw files, without header. They can be generated by all decent video
|
||||
decoders. You must specify the size of the image with the '-s' option
|
||||
if ffmpeg cannot guess it.
|
||||
The Y files use twice the resolution of the U and V files. They are
|
||||
raw files, without header. They can be generated by all decent video
|
||||
decoders. You must specify the size of the image with the @option{-s} option
|
||||
if ffmpeg cannot guess it.
|
||||
|
||||
* You can input from a RAW YUV420P file:
|
||||
|
||||
@example
|
||||
ffmpeg -i /tmp/test.yuv /tmp/out.avi
|
||||
ffmpeg -i /tmp/test.yuv /tmp/out.avi
|
||||
@end example
|
||||
|
||||
The RAW YUV420P is a file containing RAW YUV planar, for each frame first
|
||||
come the Y plane followed by U and V planes, which are half vertical and
|
||||
horizontal resolution.
|
||||
The RAW YUV420P is a file containing RAW YUV planar, for each frame first
|
||||
come the Y plane followed by U and V planes, which are half vertical and
|
||||
horizontal resolution.
|
||||
|
||||
* You can output to a RAW YUV420P file:
|
||||
|
||||
@example
|
||||
ffmpeg -i mydivx.avi -o hugefile.yuv
|
||||
ffmpeg -i mydivx.avi -o hugefile.yuv
|
||||
@end example
|
||||
|
||||
* You can set several input files and output files:
|
||||
|
||||
@example
|
||||
ffmpeg -i /tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg
|
||||
ffmpeg -i /tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg
|
||||
@end example
|
||||
|
||||
Convert the audio file a.wav and the raw yuv video file a.yuv
|
||||
to mpeg file a.mpg
|
||||
Convert the audio file a.wav and the raw yuv video file a.yuv
|
||||
to mpeg file a.mpg
|
||||
|
||||
* You can also do audio and video conversions at the same time:
|
||||
|
||||
@example
|
||||
ffmpeg -i /tmp/a.wav -ar 22050 /tmp/a.mp2
|
||||
ffmpeg -i /tmp/a.wav -ar 22050 /tmp/a.mp2
|
||||
@end example
|
||||
|
||||
Convert the sample rate of a.wav to 22050 Hz and encode it to MPEG audio.
|
||||
Convert the sample rate of a.wav to 22050 Hz and encode it to MPEG audio.
|
||||
|
||||
* You can encode to several formats at the same time and define a
|
||||
mapping from input stream to output streams:
|
||||
mapping from input stream to output streams:
|
||||
|
||||
@example
|
||||
ffmpeg -i /tmp/a.wav -ab 64 /tmp/a.mp2 -ab 128 /tmp/b.mp2 -map 0:0 -map 0:0
|
||||
ffmpeg -i /tmp/a.wav -ab 64 /tmp/a.mp2 -ab 128 /tmp/b.mp2 -map 0:0 -map 0:0
|
||||
@end example
|
||||
|
||||
Convert a.wav to a.mp2 at 64 kbits and b.mp2 at 128 kbits. '-map
|
||||
file:index' specify which input stream is used for each output
|
||||
stream, in the order of the definition of output streams.
|
||||
Convert a.wav to a.mp2 at 64 kbits and b.mp2 at 128 kbits. '-map
|
||||
file:index' specify which input stream is used for each output
|
||||
stream, in the order of the definition of output streams.
|
||||
|
||||
* You can transcode decrypted VOBs
|
||||
|
||||
@example
|
||||
ffmpeg -i snatch_1.vob -f avi -vcodec mpeg4 -b 800 -g 300 -bf 2 -acodec mp3 -ab 128 snatch.avi
|
||||
ffmpeg -i snatch_1.vob -f avi -vcodec mpeg4 -b 800 -g 300 -bf 2 -acodec mp3 -ab 128 snatch.avi
|
||||
@end example
|
||||
|
||||
This is a typical DVD ripper example, input from a VOB file, output
|
||||
to an AVI file with MPEG-4 video and MP3 audio, note that in this
|
||||
command we use B frames so the MPEG-4 stream is DivX5 compatible, GOP
|
||||
size is 300 that means an INTRA frame every 10 seconds for 29.97 fps
|
||||
input video. Also the audio stream is MP3 encoded so you need LAME
|
||||
support which is enabled using @code{--enable-mp3lame} when
|
||||
configuring. The mapping is particularly useful for DVD transcoding
|
||||
to get the desired audio language.
|
||||
This is a typical DVD ripper example, input from a VOB file, output
|
||||
to an AVI file with MPEG-4 video and MP3 audio, note that in this
|
||||
command we use B frames so the MPEG-4 stream is DivX5 compatible, GOP
|
||||
size is 300 that means an INTRA frame every 10 seconds for 29.97 fps
|
||||
input video. Also the audio stream is MP3 encoded so you need LAME
|
||||
support which is enabled using @code{--enable-mp3lame} when
|
||||
configuring. The mapping is particularly useful for DVD transcoding
|
||||
to get the desired audio language.
|
||||
|
||||
NOTE: to see the supported input formats, use @code{ffmpeg -formats}.
|
||||
NOTE: to see the supported input formats, use @code{ffmpeg -formats}.
|
||||
@c man end
|
||||
|
||||
@chapter Invocation
|
||||
|
||||
@section Syntax
|
||||
|
||||
The generic syntax is:
|
||||
The generic syntax is:
|
||||
|
||||
@example
|
||||
ffmpeg [[options][-i input_file]]... {[options] output_file}...
|
||||
@c man begin SYNOPSIS
|
||||
ffmpeg [[options][@option{-i} @var{input_file}]]... @{[options] @var{output_file}@}...
|
||||
@c man end
|
||||
@end example
|
||||
If no input file is given, audio/video grabbing is done.
|
||||
@c man begin DESCRIPTION
|
||||
If no input file is given, audio/video grabbing is done.
|
||||
|
||||
As a general rule, options are applied to the next specified
|
||||
file. For example, if you give the '-b 64' option, it sets the video
|
||||
bitrate of the next file. Format option may be needed for raw input
|
||||
files.
|
||||
As a general rule, options are applied to the next specified
|
||||
file. For example, if you give the @option{-b 64} option, it sets the video
|
||||
bitrate of the next file. Format option may be needed for raw input
|
||||
files.
|
||||
|
||||
By default, ffmpeg tries to convert as losslessly as possible: it
|
||||
uses the same audio and video parameter for the outputs as the one
|
||||
specified for the inputs.
|
||||
By default, ffmpeg tries to convert as losslessly as possible: it
|
||||
uses the same audio and video parameter for the outputs as the one
|
||||
specified for the inputs.
|
||||
@c man end
|
||||
|
||||
@c man begin OPTIONS
|
||||
@section Main options
|
||||
|
||||
@table @samp
|
||||
@table @option
|
||||
@item -L
|
||||
show license
|
||||
@item -h
|
||||
show help
|
||||
show help
|
||||
@item -formats
|
||||
show available formats, codecs, protocols, ...
|
||||
@item -f fmt
|
||||
@ -173,13 +181,11 @@ set the copyright
|
||||
@item -comment string
|
||||
set the comment
|
||||
|
||||
@item -b bitrate
|
||||
set video bitrate (in kbit/s)
|
||||
@end table
|
||||
|
||||
@section Video Options
|
||||
|
||||
@table @samp
|
||||
@table @option
|
||||
@item -s size
|
||||
set frame size [160x128]
|
||||
@item -r fps
|
||||
@ -203,7 +209,7 @@ select two pass log file name
|
||||
|
||||
@section Audio Options
|
||||
|
||||
@table @samp
|
||||
@table @option
|
||||
@item -ab bitrate
|
||||
set audio bitrate (in kbit/s)
|
||||
@item -ar freq
|
||||
@ -218,7 +224,7 @@ set audio bitrate (in kbit/s)
|
||||
|
||||
@section Advanced options
|
||||
|
||||
@table @samp
|
||||
@table @option
|
||||
@item -map file:stream
|
||||
set input stream mapping
|
||||
@item -g gop_size
|
||||
@ -264,6 +270,22 @@ calculate PSNR of compressed frames
|
||||
@item -vstats
|
||||
dump video coding statistics to file
|
||||
@end table
|
||||
@c man end
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffmpeg
|
||||
@settitle FFmpeg video converter
|
||||
|
||||
@c man begin SEEALSO
|
||||
ffserver(1), ffplay(1) and the html documentation of @file{ffmpeg}.
|
||||
@c man end
|
||||
|
||||
@c man begin AUTHOR
|
||||
Fabrice Bellard
|
||||
@c man end
|
||||
|
||||
@end ignore
|
||||
|
||||
@section Protocols
|
||||
|
||||
@ -272,47 +294,47 @@ to the standard output.
|
||||
|
||||
ffmpeg handles also many protocols specified with the URL syntax.
|
||||
|
||||
Use 'ffmpeg -formats' to have a list of the supported protocols.
|
||||
Use 'ffmpeg -formats' to have a list of the supported protocols.
|
||||
|
||||
The protocol @code{http:} is currently used only to communicate with
|
||||
ffserver (see the ffserver documentation). When ffmpeg will be a
|
||||
video player it will also be used for streaming :-)
|
||||
The protocol @code{http:} is currently used only to communicate with
|
||||
ffserver (see the ffserver documentation). When ffmpeg will be a
|
||||
video player it will also be used for streaming :-)
|
||||
|
||||
@chapter Tips
|
||||
|
||||
@itemize
|
||||
@item For streaming at very low bit rate application, use a low frame rate
|
||||
and a small gop size. This is especially true for real video where
|
||||
the Linux player does not seem to be very fast, so it can miss
|
||||
frames. An example is:
|
||||
and a small gop size. This is especially true for real video where
|
||||
the Linux player does not seem to be very fast, so it can miss
|
||||
frames. An example is:
|
||||
|
||||
@example
|
||||
ffmpeg -g 3 -r 3 -t 10 -b 50 -s qcif -f rv10 /tmp/b.rm
|
||||
ffmpeg -g 3 -r 3 -t 10 -b 50 -s qcif -f rv10 /tmp/b.rm
|
||||
@end example
|
||||
|
||||
@item The parameter 'q' which is displayed while encoding is the current
|
||||
quantizer. The value of 1 indicates that a very good quality could
|
||||
be achieved. The value of 31 indicates the worst quality. If q=31
|
||||
too often, it means that the encoder cannot compress enough to meet
|
||||
your bit rate. You must either increase the bit rate, decrease the
|
||||
frame rate or decrease the frame size.
|
||||
quantizer. The value of 1 indicates that a very good quality could
|
||||
be achieved. The value of 31 indicates the worst quality. If q=31
|
||||
too often, it means that the encoder cannot compress enough to meet
|
||||
your bit rate. You must either increase the bit rate, decrease the
|
||||
frame rate or decrease the frame size.
|
||||
|
||||
@item If your computer is not fast enough, you can speed up the
|
||||
compression at the expense of the compression ratio. You can use
|
||||
'-me zero' to speed up motion estimation, and '-intra' to disable
|
||||
completely motion estimation (you have only I frames, which means it
|
||||
is about as good as JPEG compression).
|
||||
compression at the expense of the compression ratio. You can use
|
||||
'-me zero' to speed up motion estimation, and '-intra' to disable
|
||||
completely motion estimation (you have only I frames, which means it
|
||||
is about as good as JPEG compression).
|
||||
|
||||
@item To have very low bitrates in audio, reduce the sampling frequency
|
||||
(down to 22050 kHz for mpeg audio, 22050 or 11025 for ac3).
|
||||
(down to 22050 kHz for mpeg audio, 22050 or 11025 for ac3).
|
||||
|
||||
@item To have a constant quality (but a variable bitrate), use the option
|
||||
'-qscale n' when 'n' is between 1 (excellent quality) and 31 (worst
|
||||
quality).
|
||||
'-qscale n' when 'n' is between 1 (excellent quality) and 31 (worst
|
||||
quality).
|
||||
|
||||
@item When converting video files, you can use the '-sameq' option which
|
||||
uses in the encoder the same quality factor than in the decoder. It
|
||||
allows to be almost lossless in encoding.
|
||||
uses in the encoder the same quality factor than in the decoder. It
|
||||
allows to be almost lossless in encoding.
|
||||
|
||||
@end itemize
|
||||
|
||||
|
104
doc/ffplay-doc.texi
Normal file
104
doc/ffplay-doc.texi
Normal file
@ -0,0 +1,104 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
|
||||
@settitle FFplay Documentation
|
||||
@titlepage
|
||||
@sp 7
|
||||
@center @titlefont{FFplay Documentation}
|
||||
@sp 3
|
||||
@end titlepage
|
||||
|
||||
|
||||
@chapter Introduction
|
||||
|
||||
@c man begin DESCRIPTION
|
||||
FFplay is a very simple and portable media player using the FFmpeg
|
||||
libraries and the SDL library. It is mostly used as a test bench for the
|
||||
various APIs of FFmpeg.
|
||||
@c man end
|
||||
|
||||
@chapter Invocation
|
||||
|
||||
@section Syntax
|
||||
@example
|
||||
@c man begin SYNOPSIS
|
||||
ffplay [options] @file{input_file}
|
||||
@c man end
|
||||
@end example
|
||||
|
||||
@c man begin OPTIONS
|
||||
@section Main options
|
||||
|
||||
@table @option
|
||||
@item -h
|
||||
show help
|
||||
@item -x width
|
||||
force displayed width
|
||||
@item -y height
|
||||
force displayed height
|
||||
@item -an
|
||||
disable audio
|
||||
@item -vn
|
||||
disable video
|
||||
@item -nodisp
|
||||
disable graphical display
|
||||
@item -f fmt
|
||||
force format
|
||||
@end table
|
||||
|
||||
@section Advanced options
|
||||
@table @option
|
||||
@item -stats
|
||||
show the stream duration, the codec parameters, the current position in
|
||||
the stream, and the audio/video synchronisation drift.
|
||||
@item -rtp_tcp
|
||||
force RTP/TCP protocol usage instead of RTP/UDP. It is only meaningful
|
||||
if you are doing stream with the RTSP protocol.
|
||||
@item -sync type
|
||||
set the master clock to audio (@code{type=audio}), video
|
||||
(@code{type=video}) or external (@code{type=ext}). Default is audio. The
|
||||
master clock is used to control audio-video synchronization. Most media
|
||||
players use audio as master clock, but in some cases (streaming or high
|
||||
quality broadcast) it is necessary to change that. This option is mainly
|
||||
used for debugging purposes.
|
||||
@end table
|
||||
|
||||
@section While playing
|
||||
|
||||
@table @key
|
||||
@item q, ESC
|
||||
quit
|
||||
|
||||
@item f
|
||||
toggle full screen
|
||||
|
||||
@item p, SPC
|
||||
pause
|
||||
|
||||
@item a
|
||||
cycle audio channel
|
||||
|
||||
@item v
|
||||
cycle video channel
|
||||
|
||||
@item w
|
||||
show audio waves
|
||||
@end table
|
||||
|
||||
@c man end
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffplay
|
||||
@settitle FFplay media player
|
||||
|
||||
@c man begin SEEALSO
|
||||
ffmpeg(1), ffserver(1) and the html documentation of @file{ffmpeg}.
|
||||
@c man end
|
||||
|
||||
@c man begin AUTHOR
|
||||
Fabrice Bellard
|
||||
@c man end
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
@ -10,6 +10,7 @@
|
||||
|
||||
@chapter Introduction
|
||||
|
||||
@c man begin DESCRIPTION
|
||||
FFserver is a streaming server for both audio and video. It supports
|
||||
several live feeds, streaming from files and time shifting on live feeds
|
||||
(you can seek to positions in the past on each live feed, provided you
|
||||
@ -17,8 +18,9 @@ specify a big enough feed storage in ffserver.conf).
|
||||
|
||||
This documentation covers only the streaming aspects of ffserver /
|
||||
ffmpeg. All questions about parameters for ffmpeg, codec questions,
|
||||
etc. are not covered here. Read @file{ffmpeg-doc.[texi|html]} for more
|
||||
etc. are not covered here. Read @file{ffmpeg-doc.html} for more
|
||||
information.
|
||||
@c man end
|
||||
|
||||
@chapter QuickStart
|
||||
|
||||
@ -182,4 +184,39 @@ in the future and so unlikely to useful.
|
||||
You use this by adding the ?date= to the end of the URL for the stream.
|
||||
For example: @samp{http://localhost:8080/test.asf?date=2002-07-26T23:05:00}.
|
||||
|
||||
@chapter Invocation
|
||||
@section Syntax
|
||||
@example
|
||||
@c man begin SYNOPSIS
|
||||
ffserver [options]
|
||||
@c man end
|
||||
@end example
|
||||
|
||||
@section Options
|
||||
@c man begin OPTIONS
|
||||
@table @option
|
||||
@item -L
|
||||
print the license
|
||||
@item -h
|
||||
print the help
|
||||
@item -f configfile
|
||||
use @file{configfile} instead of @file{/etc/ffserver.conf}
|
||||
@end table
|
||||
@c man end
|
||||
|
||||
@ignore
|
||||
|
||||
@setfilename ffsserver
|
||||
@settitle FFserver video server
|
||||
|
||||
@c man begin SEEALSO
|
||||
ffmpeg(1), ffplay(1) and the html documentation of @file{ffmpeg}.
|
||||
@c man end
|
||||
|
||||
@c man begin AUTHOR
|
||||
Fabrice Bellard
|
||||
@c man end
|
||||
|
||||
@end ignore
|
||||
|
||||
@bye
|
||||
|
427
doc/texi2pod.pl
Executable file
427
doc/texi2pod.pl
Executable file
@ -0,0 +1,427 @@
|
||||
#! /usr/bin/perl -w
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU CC.
|
||||
|
||||
# GNU CC 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, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# GNU CC 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 GNU CC; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
# Boston MA 02111-1307, USA.
|
||||
|
||||
# This does trivial (and I mean _trivial_) conversion of Texinfo
|
||||
# markup to Perl POD format. It's intended to be used to extract
|
||||
# something suitable for a manpage from a Texinfo document.
|
||||
|
||||
$output = 0;
|
||||
$skipping = 0;
|
||||
%sects = ();
|
||||
$section = "";
|
||||
@icstack = ();
|
||||
@endwstack = ();
|
||||
@skstack = ();
|
||||
@instack = ();
|
||||
$shift = "";
|
||||
%defs = ();
|
||||
$fnno = 1;
|
||||
$inf = "";
|
||||
$ibase = "";
|
||||
|
||||
while ($_ = shift) {
|
||||
if (/^-D(.*)$/) {
|
||||
if ($1 ne "") {
|
||||
$flag = $1;
|
||||
} else {
|
||||
$flag = shift;
|
||||
}
|
||||
$value = "";
|
||||
($flag, $value) = ($flag =~ /^([^=]+)(?:=(.+))?/);
|
||||
die "no flag specified for -D\n"
|
||||
unless $flag ne "";
|
||||
die "flags may only contain letters, digits, hyphens, dashes and underscores\n"
|
||||
unless $flag =~ /^[a-zA-Z0-9_-]+$/;
|
||||
$defs{$flag} = $value;
|
||||
} elsif (/^-/) {
|
||||
usage();
|
||||
} else {
|
||||
$in = $_, next unless defined $in;
|
||||
$out = $_, next unless defined $out;
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (defined $in) {
|
||||
$inf = gensym();
|
||||
open($inf, "<$in") or die "opening \"$in\": $!\n";
|
||||
$ibase = $1 if $in =~ m|^(.+)/[^/]+$|;
|
||||
} else {
|
||||
$inf = \*STDIN;
|
||||
}
|
||||
|
||||
if (defined $out) {
|
||||
open(STDOUT, ">$out") or die "opening \"$out\": $!\n";
|
||||
}
|
||||
|
||||
while(defined $inf) {
|
||||
while(<$inf>) {
|
||||
# Certain commands are discarded without further processing.
|
||||
/^\@(?:
|
||||
[a-z]+index # @*index: useful only in complete manual
|
||||
|need # @need: useful only in printed manual
|
||||
|(?:end\s+)?group # @group .. @end group: ditto
|
||||
|page # @page: ditto
|
||||
|node # @node: useful only in .info file
|
||||
|(?:end\s+)?ifnottex # @ifnottex .. @end ifnottex: use contents
|
||||
)\b/x and next;
|
||||
|
||||
chomp;
|
||||
|
||||
# Look for filename and title markers.
|
||||
/^\@setfilename\s+([^.]+)/ and $fn = $1, next;
|
||||
/^\@settitle\s+([^.]+)/ and $tl = postprocess($1), next;
|
||||
|
||||
# Identify a man title but keep only the one we are interested in.
|
||||
/^\@c\s+man\s+title\s+([A-Za-z0-9-]+)\s+(.+)/ and do {
|
||||
if (exists $defs{$1}) {
|
||||
$fn = $1;
|
||||
$tl = postprocess($2);
|
||||
}
|
||||
next;
|
||||
};
|
||||
|
||||
# Look for blocks surrounded by @c man begin SECTION ... @c man end.
|
||||
# This really oughta be @ifman ... @end ifman and the like, but such
|
||||
# would require rev'ing all other Texinfo translators.
|
||||
/^\@c\s+man\s+begin\s+([A-Z]+)\s+([A-Za-z0-9-]+)/ and do {
|
||||
$output = 1 if exists $defs{$2};
|
||||
$sect = $1;
|
||||
next;
|
||||
};
|
||||
/^\@c\s+man\s+begin\s+([A-Z]+)/ and $sect = $1, $output = 1, next;
|
||||
/^\@c\s+man\s+end/ and do {
|
||||
$sects{$sect} = "" unless exists $sects{$sect};
|
||||
$sects{$sect} .= postprocess($section);
|
||||
$section = "";
|
||||
$output = 0;
|
||||
next;
|
||||
};
|
||||
|
||||
# handle variables
|
||||
/^\@set\s+([a-zA-Z0-9_-]+)\s*(.*)$/ and do {
|
||||
$defs{$1} = $2;
|
||||
next;
|
||||
};
|
||||
/^\@clear\s+([a-zA-Z0-9_-]+)/ and do {
|
||||
delete $defs{$1};
|
||||
next;
|
||||
};
|
||||
|
||||
next unless $output;
|
||||
|
||||
# Discard comments. (Can't do it above, because then we'd never see
|
||||
# @c man lines.)
|
||||
/^\@c\b/ and next;
|
||||
|
||||
# End-block handler goes up here because it needs to operate even
|
||||
# if we are skipping.
|
||||
/^\@end\s+([a-z]+)/ and do {
|
||||
# Ignore @end foo, where foo is not an operation which may
|
||||
# cause us to skip, if we are presently skipping.
|
||||
my $ended = $1;
|
||||
next if $skipping && $ended !~ /^(?:ifset|ifclear|ignore|menu|iftex)$/;
|
||||
|
||||
die "\@end $ended without \@$ended at line $.\n" unless defined $endw;
|
||||
die "\@$endw ended by \@end $ended at line $.\n" unless $ended eq $endw;
|
||||
|
||||
$endw = pop @endwstack;
|
||||
|
||||
if ($ended =~ /^(?:ifset|ifclear|ignore|menu|iftex)$/) {
|
||||
$skipping = pop @skstack;
|
||||
next;
|
||||
} elsif ($ended =~ /^(?:example|smallexample|display)$/) {
|
||||
$shift = "";
|
||||
$_ = ""; # need a paragraph break
|
||||
} elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) {
|
||||
$_ = "\n=back\n";
|
||||
$ic = pop @icstack;
|
||||
} else {
|
||||
die "unknown command \@end $ended at line $.\n";
|
||||
}
|
||||
};
|
||||
|
||||
# We must handle commands which can cause skipping even while we
|
||||
# are skipping, otherwise we will not process nested conditionals
|
||||
# correctly.
|
||||
/^\@ifset\s+([a-zA-Z0-9_-]+)/ and do {
|
||||
push @endwstack, $endw;
|
||||
push @skstack, $skipping;
|
||||
$endw = "ifset";
|
||||
$skipping = 1 unless exists $defs{$1};
|
||||
next;
|
||||
};
|
||||
|
||||
/^\@ifclear\s+([a-zA-Z0-9_-]+)/ and do {
|
||||
push @endwstack, $endw;
|
||||
push @skstack, $skipping;
|
||||
$endw = "ifclear";
|
||||
$skipping = 1 if exists $defs{$1};
|
||||
next;
|
||||
};
|
||||
|
||||
/^\@(ignore|menu|iftex)\b/ and do {
|
||||
push @endwstack, $endw;
|
||||
push @skstack, $skipping;
|
||||
$endw = $1;
|
||||
$skipping = 1;
|
||||
next;
|
||||
};
|
||||
|
||||
next if $skipping;
|
||||
|
||||
# Character entities. First the ones that can be replaced by raw text
|
||||
# or discarded outright:
|
||||
s/\@copyright\{\}/(c)/g;
|
||||
s/\@dots\{\}/.../g;
|
||||
s/\@enddots\{\}/..../g;
|
||||
s/\@([.!? ])/$1/g;
|
||||
s/\@[:-]//g;
|
||||
s/\@bullet(?:\{\})?/*/g;
|
||||
s/\@TeX\{\}/TeX/g;
|
||||
s/\@pounds\{\}/\#/g;
|
||||
s/\@minus(?:\{\})?/-/g;
|
||||
s/\\,/,/g;
|
||||
|
||||
# Now the ones that have to be replaced by special escapes
|
||||
# (which will be turned back into text by unmunge())
|
||||
s/&/&/g;
|
||||
s/\@\{/{/g;
|
||||
s/\@\}/}/g;
|
||||
s/\@\@/&at;/g;
|
||||
|
||||
# Inside a verbatim block, handle @var specially.
|
||||
if ($shift ne "") {
|
||||
s/\@var\{([^\}]*)\}/<$1>/g;
|
||||
}
|
||||
|
||||
# POD doesn't interpret E<> inside a verbatim block.
|
||||
if ($shift eq "") {
|
||||
s/</</g;
|
||||
s/>/>/g;
|
||||
} else {
|
||||
s/</</g;
|
||||
s/>/>/g;
|
||||
}
|
||||
|
||||
# Single line command handlers.
|
||||
|
||||
/^\@include\s+(.+)$/ and do {
|
||||
push @instack, $inf;
|
||||
$inf = gensym();
|
||||
|
||||
# Try cwd and $ibase.
|
||||
open($inf, "<" . $1)
|
||||
or open($inf, "<" . $ibase . "/" . $1)
|
||||
or die "cannot open $1 or $ibase/$1: $!\n";
|
||||
next;
|
||||
};
|
||||
|
||||
/^\@(?:section|unnumbered|unnumberedsec|center)\s+(.+)$/
|
||||
and $_ = "\n=head2 $1\n";
|
||||
/^\@subsection\s+(.+)$/
|
||||
and $_ = "\n=head3 $1\n";
|
||||
|
||||
# Block command handlers:
|
||||
/^\@itemize\s+(\@[a-z]+|\*|-)/ and do {
|
||||
push @endwstack, $endw;
|
||||
push @icstack, $ic;
|
||||
$ic = $1;
|
||||
$_ = "\n=over 4\n";
|
||||
$endw = "itemize";
|
||||
};
|
||||
|
||||
/^\@enumerate(?:\s+([a-zA-Z0-9]+))?/ and do {
|
||||
push @endwstack, $endw;
|
||||
push @icstack, $ic;
|
||||
if (defined $1) {
|
||||
$ic = $1 . ".";
|
||||
} else {
|
||||
$ic = "1.";
|
||||
}
|
||||
$_ = "\n=over 4\n";
|
||||
$endw = "enumerate";
|
||||
};
|
||||
|
||||
/^\@([fv]?table)\s+(\@[a-z]+)/ and do {
|
||||
push @endwstack, $endw;
|
||||
push @icstack, $ic;
|
||||
$endw = $1;
|
||||
$ic = $2;
|
||||
$ic =~ s/\@(?:samp|strong|key|gcctabopt|option|env)/B/;
|
||||
$ic =~ s/\@(?:code|kbd)/C/;
|
||||
$ic =~ s/\@(?:dfn|var|emph|cite|i)/I/;
|
||||
$ic =~ s/\@(?:file)/F/;
|
||||
$_ = "\n=over 4\n";
|
||||
};
|
||||
|
||||
/^\@((?:small)?example|display)/ and do {
|
||||
push @endwstack, $endw;
|
||||
$endw = $1;
|
||||
$shift = "\t";
|
||||
$_ = ""; # need a paragraph break
|
||||
};
|
||||
|
||||
/^\@itemx?\s*(.+)?$/ and do {
|
||||
if (defined $1) {
|
||||
# Entity escapes prevent munging by the <> processing below.
|
||||
$_ = "\n=item $ic\<$1\>\n";
|
||||
} else {
|
||||
$_ = "\n=item $ic\n";
|
||||
$ic =~ y/A-Ya-y/B-Zb-z/;
|
||||
$ic =~ s/(\d+)/$1 + 1/eg;
|
||||
}
|
||||
};
|
||||
|
||||
$section .= $shift.$_."\n";
|
||||
}
|
||||
# End of current file.
|
||||
close($inf);
|
||||
$inf = pop @instack;
|
||||
}
|
||||
|
||||
die "No filename or title\n" unless defined $fn && defined $tl;
|
||||
|
||||
$sects{NAME} = "$fn \- $tl\n";
|
||||
$sects{FOOTNOTES} .= "=back\n" if exists $sects{FOOTNOTES};
|
||||
|
||||
for $sect (qw(NAME SYNOPSIS DESCRIPTION OPTIONS EXAMPLES ENVIRONMENT FILES
|
||||
BUGS NOTES FOOTNOTES SEEALSO AUTHOR COPYRIGHT)) {
|
||||
if(exists $sects{$sect}) {
|
||||
$head = $sect;
|
||||
$head =~ s/SEEALSO/SEE ALSO/;
|
||||
print "=head1 $head\n\n";
|
||||
print scalar unmunge ($sects{$sect});
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub usage
|
||||
{
|
||||
die "usage: $0 [-D toggle...] [infile [outfile]]\n";
|
||||
}
|
||||
|
||||
sub postprocess
|
||||
{
|
||||
local $_ = $_[0];
|
||||
|
||||
# @value{foo} is replaced by whatever 'foo' is defined as.
|
||||
while (m/(\@value\{([a-zA-Z0-9_-]+)\})/g) {
|
||||
if (! exists $defs{$2}) {
|
||||
print STDERR "Option $2 not defined\n";
|
||||
s/\Q$1\E//;
|
||||
} else {
|
||||
$value = $defs{$2};
|
||||
s/\Q$1\E/$value/;
|
||||
}
|
||||
}
|
||||
|
||||
# Formatting commands.
|
||||
# Temporary escape for @r.
|
||||
s/\@r\{([^\}]*)\}/R<$1>/g;
|
||||
s/\@(?:dfn|var|emph|cite|i)\{([^\}]*)\}/I<$1>/g;
|
||||
s/\@(?:code|kbd)\{([^\}]*)\}/C<$1>/g;
|
||||
s/\@(?:gccoptlist|samp|strong|key|option|env|command|b)\{([^\}]*)\}/B<$1>/g;
|
||||
s/\@sc\{([^\}]*)\}/\U$1/g;
|
||||
s/\@file\{([^\}]*)\}/F<$1>/g;
|
||||
s/\@w\{([^\}]*)\}/S<$1>/g;
|
||||
s/\@(?:dmn|math)\{([^\}]*)\}/$1/g;
|
||||
|
||||
# Cross references are thrown away, as are @noindent and @refill.
|
||||
# (@noindent is impossible in .pod, and @refill is unnecessary.)
|
||||
# @* is also impossible in .pod; we discard it and any newline that
|
||||
# follows it. Similarly, our macro @gol must be discarded.
|
||||
|
||||
s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g;
|
||||
s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g;
|
||||
s/;\s+\@pxref\{(?:[^\}]*)\}//g;
|
||||
s/\@noindent\s*//g;
|
||||
s/\@refill//g;
|
||||
s/\@gol//g;
|
||||
s/\@\*\s*\n?//g;
|
||||
|
||||
# @uref can take one, two, or three arguments, with different
|
||||
# semantics each time. @url and @email are just like @uref with
|
||||
# one argument, for our purposes.
|
||||
s/\@(?:uref|url|email)\{([^\},]*)\}/<B<$1>>/g;
|
||||
s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g;
|
||||
s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g;
|
||||
|
||||
# Turn B<blah I<blah> blah> into B<blah> I<blah> B<blah> to
|
||||
# match Texinfo semantics of @emph inside @samp. Also handle @r
|
||||
# inside bold.
|
||||
s/</</g;
|
||||
s/>/>/g;
|
||||
1 while s/B<((?:[^<>]|I<[^<>]*>)*)R<([^>]*)>/B<$1>${2}B</g;
|
||||
1 while (s/B<([^<>]*)I<([^>]+)>/B<$1>I<$2>B</g);
|
||||
1 while (s/I<([^<>]*)B<([^>]+)>/I<$1>B<$2>I</g);
|
||||
s/[BI]<>//g;
|
||||
s/([BI])<(\s+)([^>]+)>/$2$1<$3>/g;
|
||||
s/([BI])<([^>]+?)(\s+)>/$1<$2>$3/g;
|
||||
|
||||
# Extract footnotes. This has to be done after all other
|
||||
# processing because otherwise the regexp will choke on formatting
|
||||
# inside @footnote.
|
||||
while (/\@footnote/g) {
|
||||
s/\@footnote\{([^\}]+)\}/[$fnno]/;
|
||||
add_footnote($1, $fnno);
|
||||
$fnno++;
|
||||
}
|
||||
|
||||
return $_;
|
||||
}
|
||||
|
||||
sub unmunge
|
||||
{
|
||||
# Replace escaped symbols with their equivalents.
|
||||
local $_ = $_[0];
|
||||
|
||||
s/</E<lt>/g;
|
||||
s/>/E<gt>/g;
|
||||
s/{/\{/g;
|
||||
s/}/\}/g;
|
||||
s/&at;/\@/g;
|
||||
s/&/&/g;
|
||||
return $_;
|
||||
}
|
||||
|
||||
sub add_footnote
|
||||
{
|
||||
unless (exists $sects{FOOTNOTES}) {
|
||||
$sects{FOOTNOTES} = "\n=over 4\n\n";
|
||||
}
|
||||
|
||||
$sects{FOOTNOTES} .= "=item $fnno.\n\n"; $fnno++;
|
||||
$sects{FOOTNOTES} .= $_[0];
|
||||
$sects{FOOTNOTES} .= "\n\n";
|
||||
}
|
||||
|
||||
# stolen from Symbol.pm
|
||||
{
|
||||
my $genseq = 0;
|
||||
sub gensym
|
||||
{
|
||||
my $name = "GEN" . $genseq++;
|
||||
my $ref = \*{$name};
|
||||
delete $::{$name};
|
||||
return $ref;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user