2002-02-02 04:55:52 +00:00
|
|
|
#!/usr/bin/perl
|
|
|
|
#
|
2002-03-10 15:06:43 +00:00
|
|
|
# this utility converts a Texinfo file into DocBook XML format.
|
2002-02-02 04:55:52 +00:00
|
|
|
#
|
|
|
|
use File::Basename;
|
|
|
|
use FileHandle;
|
|
|
|
use HTML::Entities;
|
|
|
|
|
2002-05-25 22:44:15 +00:00
|
|
|
$VERSION = "0.4.2-cvs";
|
2002-02-02 04:55:52 +00:00
|
|
|
|
|
|
|
$errors = 0;
|
|
|
|
$error = 0;
|
|
|
|
|
|
|
|
# runtime options
|
|
|
|
#
|
2002-02-18 09:04:56 +00:00
|
|
|
$maxerrors = 1;
|
2002-02-02 04:55:52 +00:00
|
|
|
$verbose = 0;
|
2002-02-07 07:34:47 +00:00
|
|
|
$outputtype = "HTML";
|
2002-02-16 09:24:36 +00:00
|
|
|
$maxrunonlines = 20;
|
2002-02-02 04:55:52 +00:00
|
|
|
|
|
|
|
# files
|
|
|
|
#
|
|
|
|
$requestedfile = "";
|
|
|
|
$outputfile = "";
|
|
|
|
$outfh = new FileHandle;
|
|
|
|
$logfile = "";
|
|
|
|
$logfh = new FileHandle;
|
|
|
|
|
|
|
|
# the following are flags to maintain state
|
|
|
|
#
|
|
|
|
# docbook structure flags
|
|
|
|
#
|
|
|
|
$inabstract = 1;
|
|
|
|
$inappendix = 0;
|
|
|
|
$insect1 = 0;
|
|
|
|
$insect2 = 0;
|
|
|
|
$insect3 = 0;
|
2002-02-18 09:04:56 +00:00
|
|
|
$insect4 = 0;
|
|
|
|
@nest = (); # stack, tracks nested structures 'table', 'multi', 'itemized', 'ordered'
|
|
|
|
@inrow = ();
|
|
|
|
@incol = ();
|
|
|
|
@infirstcol = ();
|
|
|
|
@tableformat = ();
|
|
|
|
@initem = ();
|
2002-02-02 04:55:52 +00:00
|
|
|
$informalpara = 0;
|
|
|
|
$inpara = 0;
|
2002-02-21 10:52:32 +00:00
|
|
|
$inmenu = 0;
|
2002-05-25 15:32:11 +00:00
|
|
|
$lang = "en"; # Used for keeping the language of the document
|
2002-02-02 04:55:52 +00:00
|
|
|
|
|
|
|
# these maintain internal program state
|
2002-02-05 04:52:38 +00:00
|
|
|
#
|
2002-02-02 04:55:52 +00:00
|
|
|
$line = "";
|
|
|
|
$originalline = "";
|
|
|
|
$currentfile = "";
|
|
|
|
$currentline = "";
|
|
|
|
$saveline = "";
|
|
|
|
$badbracketlines = 0;
|
|
|
|
$badbracketstartline = 0;
|
|
|
|
$seekend = "";
|
2002-02-21 10:52:32 +00:00
|
|
|
$literaltag = ''; # inline literal tag we're inside of
|
|
|
|
$literalendtag = ''; # tag that will end the block
|
|
|
|
@literal = (); # stacks for above tags
|
|
|
|
@literalend = ();
|
|
|
|
$suppressconversion = 0; # causes no conversion of @-commands
|
|
|
|
$suppresspara = 0; # causes no insertion of <para> tags
|
2002-02-02 04:55:52 +00:00
|
|
|
|
|
|
|
# here, we hold onto meta-data that we will need to build
|
|
|
|
# the article or book header structures.
|
|
|
|
#
|
|
|
|
$sgmlfile = "";
|
|
|
|
$title = "";
|
|
|
|
$authorname = "";
|
|
|
|
$buf = "";
|
|
|
|
|
2002-02-05 04:52:38 +00:00
|
|
|
# these are used when parsing the line for commands
|
|
|
|
#
|
|
|
|
$command;
|
|
|
|
$tag;
|
|
|
|
$tagplain;
|
|
|
|
$contents;
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
# these hold information about the node we are currently in, if any
|
|
|
|
#
|
2002-02-19 05:02:23 +00:00
|
|
|
$nodename = '';
|
|
|
|
$nodetitle = '';
|
|
|
|
$nodenext = '';
|
|
|
|
$nodeprev = '';
|
|
|
|
$nodeup = '';
|
|
|
|
$nodeid = '';
|
2002-02-02 04:55:52 +00:00
|
|
|
$nodeinit = 0;
|
|
|
|
|
|
|
|
# remember this hierarchical information for every node
|
|
|
|
# we use it if the node doesn't specify a level.
|
|
|
|
#
|
2002-02-15 14:30:00 +00:00
|
|
|
%nodenames = ();
|
|
|
|
%nodeanchors = ();
|
|
|
|
%nodenexts = ();
|
|
|
|
%nodeprevs = ();
|
|
|
|
%nodeups = ();
|
|
|
|
%nodelevels = ();
|
2002-02-02 04:55:52 +00:00
|
|
|
|
|
|
|
# holds user variables
|
|
|
|
#
|
|
|
|
%setvalues = ();
|
|
|
|
%ifsets = ();
|
|
|
|
|
|
|
|
# this is used to build a list of index entries to be written when requested
|
|
|
|
#
|
|
|
|
%indexes = ();
|
|
|
|
|
|
|
|
# These are used for keeping state on the most recent search of any of the following hashes
|
|
|
|
#
|
|
|
|
$pattern = "";
|
|
|
|
$action = "";
|
2002-02-05 04:52:38 +00:00
|
|
|
$replacement = "";
|
2002-02-02 04:55:52 +00:00
|
|
|
|
|
|
|
# In the following hash, the perl expressions are used to search
|
|
|
|
# each line of the input file. If matched, the Action field defines
|
|
|
|
# what to do with it.
|
|
|
|
#
|
|
|
|
# Note that @-Commands of this type must be at the beginning of the line.
|
|
|
|
#
|
|
|
|
# TODO: put these in a .conf file so it can be tweaked or customized
|
|
|
|
#
|
|
|
|
# Actions:
|
|
|
|
#
|
2002-03-10 15:06:43 +00:00
|
|
|
# ALIAS Create an alias to another command
|
|
|
|
# APPENDIX Begin an appentix
|
2002-02-02 04:55:52 +00:00
|
|
|
# BYE Stop processing the file
|
2002-03-10 15:06:43 +00:00
|
|
|
# CLEAR Clear a variable
|
|
|
|
# COMMENT Insert a comment
|
|
|
|
# DEFFN Define a function
|
|
|
|
# DEFINFOENCLOSE Load a customized highlighting pattern
|
|
|
|
# DROPBLOCK Drop the whole block on the floor
|
|
|
|
# DROPLINE Drop it on the floor
|
|
|
|
# IFCLEAR Test a variable
|
|
|
|
# IFSET Test a variable
|
2002-02-02 04:55:52 +00:00
|
|
|
# INDEX An index entry
|
2002-03-10 15:06:43 +00:00
|
|
|
# ITEM An item in a list or table
|
|
|
|
# LITERALBLOCK Literal layout block
|
|
|
|
# MACRO Record a program macro
|
|
|
|
# META Meta-Data
|
|
|
|
# MULTITABLE Begin a multi column table
|
|
|
|
# NODE A Texinfo node
|
2002-02-02 04:55:52 +00:00
|
|
|
# ORDEREDLIST Numbered (enumerated) list
|
|
|
|
# ORDEREDLISTEND End an enumerated list
|
|
|
|
# SECT? One of the sectioning commands
|
2002-03-10 15:06:43 +00:00
|
|
|
# SEEKEND Skip everything until you find the corresponding @end tag
|
2002-02-02 04:55:52 +00:00
|
|
|
# SET Set a variable
|
2002-03-10 15:06:43 +00:00
|
|
|
# TABLE Begin a table
|
|
|
|
# TABLEEND End a table
|
2002-02-02 04:55:52 +00:00
|
|
|
#
|
|
|
|
# @-Command Action
|
|
|
|
%patterns = (
|
2002-02-07 07:34:47 +00:00
|
|
|
'\input' =>'DROPLINE',
|
2002-02-21 11:47:02 +00:00
|
|
|
'o\input' =>'DROPLINE',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@alias' =>'ALIAS',
|
|
|
|
'@author' =>'META',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@bye' =>'BYE',
|
2002-02-21 11:47:02 +00:00
|
|
|
'@cartouche' =>'DROPLINE',
|
|
|
|
'@end cartouche' =>'DROPLINE',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@clear' =>'CLEAR',
|
2002-02-19 05:02:23 +00:00
|
|
|
# '@c' =>'COMMENT', # handled specially
|
|
|
|
# '@comment' =>'COMMENT',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@contents' =>'DROPLINE',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@defcodeindex' =>'DROPLINE', # TODO
|
|
|
|
'@deffn' =>'DEFFN',
|
|
|
|
'@end deffn' =>'DROPLINE',
|
|
|
|
'@deffnx' =>'DEFFN',
|
|
|
|
'@end deffnx' =>'DROPLINE',
|
|
|
|
'@defmac' =>'DEFFN',
|
|
|
|
'@end defmac' =>'DROPLINE',
|
|
|
|
'@defmacx' =>'DEFFN',
|
|
|
|
'@end defmacx' =>'DROPLINE',
|
|
|
|
'@defun' =>'DEFFN',
|
|
|
|
'@end defun' =>'DROPLINE',
|
|
|
|
'@defunx' =>'DEFFN',
|
|
|
|
'@end defunx' =>'DROPLINE',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@defindex' =>'DROPLINE', # TODO
|
|
|
|
'@definfoenclose' =>'DEFINFOENCLOSE',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@defspec' =>'DEFFN',
|
|
|
|
'@end defspec' =>'DROPLINE',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@dircategory' =>'DROPLINE',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@direntry' =>'SEEKEND',
|
2002-02-21 10:52:32 +00:00
|
|
|
'@display' =>'LITERALBLOCK',
|
2002-05-25 15:32:11 +00:00
|
|
|
'@documentlanguage' =>'META',
|
2002-03-10 15:06:43 +00:00
|
|
|
# '@end display' =>'DROPLINE',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@enumerate' =>'ORDEREDLIST',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@end enumerate' =>'ORDEREDLISTEND',
|
|
|
|
'@example' =>'LITERALBLOCK',
|
2002-03-10 15:06:43 +00:00
|
|
|
# '@end example' =>'DROPLINE',
|
2002-02-21 10:52:32 +00:00
|
|
|
'@exdent' =>'DROPLINE',
|
2002-02-21 11:47:02 +00:00
|
|
|
'@finalout' =>'DROPLINE',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@footnotestyle' =>'DROPLINE',
|
2002-03-02 16:10:55 +00:00
|
|
|
'@format' =>'LITERALBLOCK',
|
2002-03-10 15:06:43 +00:00
|
|
|
# '@end format' =>'DROPLINE',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@flushleft' =>'DROPLINE',
|
|
|
|
'@end flushleft' =>'DROPLINE',
|
|
|
|
'@flushright' =>'DROPLINE',
|
|
|
|
'@end flushright' =>'DROPLINE',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@headings' =>'DROPLINE',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@html' =>'SEEKEND',
|
2002-03-10 15:06:43 +00:00
|
|
|
'@end html' =>'DROPLINE',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@ifhtml' =>'SEEKEND',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@end ifhtml' =>'DROPLINE',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@ifinfo' =>'SEEKEND',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@end ifinfo' =>'DROPLINE',
|
|
|
|
'@ifnothtml' =>'SEEKEND',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@end ifnothtml' =>'DROPLINE',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@ifnotinfo' =>'SEEKEND',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@end ifnotinfo' =>'DROPLINE',
|
|
|
|
'@ifnottex' =>'SEEKEND',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@end ifnottex' =>'DROPLINE',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@ifset' =>'IFSET', # handled like SEEKEND
|
2002-02-15 14:30:00 +00:00
|
|
|
'@end ifset' =>'DROPLINE', # or ignored, so ignore this too
|
2002-02-07 07:34:47 +00:00
|
|
|
'@ifclear' =>'IFCLEAR',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@end ifclear' =>'DROPLINE',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@iftex' =>'DROPLINE',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@end iftex' =>'DROPLINE',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@ignore' =>'SEEKEND',
|
|
|
|
'@itemize' =>'ITEMIZEDLIST',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@end itemize' =>'ITEMIZEDLISTEND',
|
|
|
|
'@item' =>'ITEM',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@itemx' =>'ITEM',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@lisp' =>'LITERALBLOCK',
|
2002-03-10 15:06:43 +00:00
|
|
|
# '@end lisp' =>'DROPLINE',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@macro' =>'MACRO',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@majorheading' =>'SECT1',
|
2002-02-21 10:52:32 +00:00
|
|
|
'@menu' =>'SEEKEND',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@opindex' =>'DROPLINE', # TODO
|
|
|
|
'@need' =>'DROP2',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@node' =>'NODE',
|
|
|
|
'@page' =>'DROPLINE',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@paragraphindent' =>'DROPLINE',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@printindex' =>'DROPLINE', # TODO
|
|
|
|
'@set' =>'SET',
|
|
|
|
'@setchapternewpage' =>'DROPLINE',
|
|
|
|
'@setfilename' =>'META',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@settitle' =>'META',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@shorttitlepage' =>'DROPLINE',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@smallbook' =>'DROPLINE',
|
|
|
|
'@smallexample' =>'LITERALBLOCK',
|
2002-03-10 15:06:43 +00:00
|
|
|
# '@end smallexample' =>'DROPLINE',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@sp' =>'DROPLINE',
|
2002-03-17 06:16:59 +00:00
|
|
|
'@synindex' =>'DROPLINE',
|
2002-02-21 11:47:02 +00:00
|
|
|
'@ftable' =>'TABLE',
|
|
|
|
'@end ftable' =>'TABLEEND',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@table' =>'TABLE',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@end table' =>'TABLEEND',
|
2002-02-16 14:33:24 +00:00
|
|
|
'@multitable' =>'MULTITABLE',
|
|
|
|
'@end multitable' =>'TABLEEND',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@summarycontents' =>'DROPLINE',
|
|
|
|
'@syncodeindex' =>'DROPLINE', # TODO
|
2002-02-15 14:30:00 +00:00
|
|
|
'@tex' =>'SEEKEND',
|
|
|
|
'@titlepage' =>'SEEKEND',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@verbatim' =>'LITERALBLOCK',
|
2002-03-10 15:06:43 +00:00
|
|
|
# '@end verbatim' =>'DROPLINE',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@vtable' =>'TABLE',
|
|
|
|
'@end vtable' =>'TABLEEND',
|
|
|
|
|
2002-02-15 14:30:00 +00:00
|
|
|
'@top' =>'SECT1', # sectioning commands
|
2002-02-07 07:34:47 +00:00
|
|
|
'@chapter' =>'SECT1',
|
|
|
|
'@section' =>'SECT2',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@subsection' =>'SECT3',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@subsubsection' =>'SECT4',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@centerchap' =>'SECT1',
|
|
|
|
'@unnumbered' =>'SECT1',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@unnumberedsec' =>'SECT2',
|
|
|
|
'@unnumberedsubsec' =>'SECT3',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@unnumberedsubsubsec' =>'SECT4',
|
|
|
|
'@chapheading' =>'SECT1',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@heading' =>'SECT2',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@subheading' =>'SECT3',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@subsubheading' =>'SECT4',
|
|
|
|
'@appendix' =>'APPENDIX',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@appendixsec' =>'SECT1',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@appendixsubsec' =>'SECT2',
|
2002-02-15 14:30:00 +00:00
|
|
|
'@appendixsubsubsec' =>'SECT3',
|
2002-02-18 09:04:56 +00:00
|
|
|
|
2002-05-25 22:44:15 +00:00
|
|
|
'@cindex' =>'CINDEX', # TODO (temporary placement)
|
2002-02-21 11:47:02 +00:00
|
|
|
'@cmindex' =>'DROPLINE',
|
|
|
|
'@cvindex' =>'DROPLINE',
|
2002-05-25 22:44:15 +00:00
|
|
|
'@findex' =>'CINDEX',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@kindex' =>'DROPLINE',
|
|
|
|
'@pindex' =>'DROPLINE',
|
|
|
|
'@tindex' =>'DROPLINE',
|
2002-02-21 11:47:02 +00:00
|
|
|
'@trindex' =>'DROPLINE',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@vindex' =>'DROPLINE',
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
);
|
|
|
|
|
2002-02-16 14:33:24 +00:00
|
|
|
# These are one-for-one string substitutions
|
2002-02-02 04:55:52 +00:00
|
|
|
#
|
2002-02-16 14:33:24 +00:00
|
|
|
# Many of them are replaced by ISO-8879 codes for international characters,
|
|
|
|
# used by HTML as well as XML. See that spec for more information.
|
|
|
|
# (One version is at http://www.w3.org/TR/html4/sgml/entities.html)
|
|
|
|
#
|
|
|
|
# There are special cases, e.g. "@@", which is the escaped form of @.
|
2002-02-02 04:55:52 +00:00
|
|
|
# We do not handle @@ here, because it has to come after all other
|
|
|
|
# @-commands have been processed.
|
2002-02-16 14:33:24 +00:00
|
|
|
#
|
|
|
|
# These commands can have {} following them, but if so the whole
|
|
|
|
# construction must be listed, e.g., @AA{}.
|
2002-02-02 04:55:52 +00:00
|
|
|
#
|
|
|
|
# It's fine to replace these with nothing if you want them to be
|
|
|
|
# simply dropped on the floor.
|
|
|
|
#
|
2002-02-16 14:33:24 +00:00
|
|
|
# Neither side needs to be escaped.
|
2002-02-02 04:55:52 +00:00
|
|
|
#
|
2002-02-18 09:04:56 +00:00
|
|
|
# The array is for sorting keys.
|
|
|
|
# They are sorted in descending order and then iterated, to make sure
|
|
|
|
# @ss comes before @s, so we replace them correctly later.
|
|
|
|
#
|
|
|
|
@substitutionkeys = ();
|
2002-02-02 04:55:52 +00:00
|
|
|
%substitutions = (
|
2002-02-16 14:33:24 +00:00
|
|
|
# '@@' =>'@', # handled specially to simplify parsing
|
2002-02-16 09:24:36 +00:00
|
|
|
# '@\{' =>'{',
|
|
|
|
# '@\}' =>'}',
|
2002-02-21 14:04:05 +00:00
|
|
|
# '@,{c}' =>'¸',
|
2002-02-16 14:33:24 +00:00
|
|
|
|
2002-02-21 10:52:32 +00:00
|
|
|
'@ ' =>' ', # punctuation and typographic characters
|
|
|
|
'@-' =>'¯',
|
2002-02-05 04:52:38 +00:00
|
|
|
'@.' =>'.',
|
|
|
|
'@!' =>'!',
|
2002-02-16 14:33:24 +00:00
|
|
|
'@?' =>'?',
|
2002-02-21 11:47:02 +00:00
|
|
|
'@"' =>'"',
|
2002-02-16 14:33:24 +00:00
|
|
|
'@exclamdown{}' =>'¡',
|
|
|
|
'@questiondown{}' =>'¿',
|
|
|
|
'@pounds{}' =>'£',
|
|
|
|
'@bullet{}' =>'*',
|
|
|
|
'@copyright{}' =>'©',
|
|
|
|
'@dots{}' =>'…',
|
|
|
|
'@minus{}' =>'-',
|
|
|
|
'@TeX{}' =>'TeX',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@enddots{}' =>'…',
|
2002-02-16 14:33:24 +00:00
|
|
|
|
|
|
|
'@:' =>'', # text layout, has no meaning in DocBook
|
|
|
|
'@=' =>'', # which is a semantic language.
|
|
|
|
'@*' =>'', # Layout issues are handled in XSLT.
|
2002-02-05 04:52:38 +00:00
|
|
|
'@s' =>' ',
|
2002-02-16 14:33:24 +00:00
|
|
|
'@center' =>'',
|
|
|
|
'@group' =>'',
|
|
|
|
'@end group' =>'',
|
|
|
|
'@noindent' =>'',
|
|
|
|
'@refill' =>'',
|
|
|
|
|
|
|
|
# accented characters
|
|
|
|
#
|
|
|
|
# Note that glyphs we cannot support in DocBook are represented by
|
2002-02-18 09:04:56 +00:00
|
|
|
# an appended character. Since this is so very similar to the
|
|
|
|
# @definfoenclose style of custom highlighting, they are handled
|
|
|
|
# in that section.
|
2002-02-16 14:33:24 +00:00
|
|
|
#
|
|
|
|
'@"A' =>'Ä', # umlaut
|
2002-02-05 04:52:38 +00:00
|
|
|
'@"E' =>'Ë',
|
|
|
|
'@"I' =>'Ï',
|
|
|
|
'@"O' =>'Ö',
|
|
|
|
'@"U' =>'Ü',
|
|
|
|
'@"a' =>'ä',
|
|
|
|
'@"e' =>'ë',
|
|
|
|
'@"i' =>'ï',
|
|
|
|
'@"o' =>'ö',
|
|
|
|
'@"u' =>'ü',
|
2002-02-16 14:33:24 +00:00
|
|
|
'@' . "'" . 'A' =>'Á', # acute accent
|
2002-02-05 04:52:38 +00:00
|
|
|
'@' . "'" . 'E' =>'É',
|
|
|
|
'@' . "'" . 'I' =>'Í',
|
|
|
|
'@' . "'" . 'O' =>'Ó',
|
|
|
|
'@' . "'" . 'U' =>'Ú',
|
|
|
|
'@' . "'" . 'a' =>'á',
|
|
|
|
'@' . "'" . 'e' =>'é',
|
|
|
|
'@' . "'" . 'i' =>'í',
|
|
|
|
'@' . "'" . 'o' =>'ó',
|
|
|
|
'@' . "'" . 'u' =>'ú',
|
2002-02-16 14:33:24 +00:00
|
|
|
'@`A' =>'À', # grave accent
|
2002-02-05 04:52:38 +00:00
|
|
|
'@`E' =>'È',
|
|
|
|
'@`I' =>'Ì',
|
|
|
|
'@`O' =>'Ò',
|
|
|
|
'@`U' =>'Ù',
|
|
|
|
'@`a' =>'à',
|
|
|
|
'@`e' =>'è',
|
|
|
|
'@`i' =>'ì',
|
|
|
|
'@`o' =>'ò',
|
|
|
|
'@`u' =>'ù',
|
2002-02-16 14:33:24 +00:00
|
|
|
'@^A' =>'Â', # circumflex
|
|
|
|
'@^E' =>'Ê',
|
|
|
|
'@^I' =>'Î',
|
|
|
|
'@^O' =>'Ô',
|
|
|
|
'@^U' =>'Û',
|
|
|
|
'@^a' =>'â',
|
|
|
|
'@^e' =>'ê',
|
|
|
|
'@^i' =>'î',
|
|
|
|
'@^o' =>'ô',
|
|
|
|
'@^u' =>'û',
|
|
|
|
'@~A' =>'Ã', # tilde
|
2002-02-18 09:04:56 +00:00
|
|
|
'@~N' =>'Ñ',
|
2002-02-05 04:52:38 +00:00
|
|
|
'@~O' =>'Õ',
|
|
|
|
'@~a' =>'ã',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@~n' =>'ñ',
|
2002-02-05 04:52:38 +00:00
|
|
|
'@~o' =>'õ',
|
2002-02-16 14:33:24 +00:00
|
|
|
'@=A' =>'A¯', # macron
|
|
|
|
'@=E' =>'E¯',
|
|
|
|
'@=I' =>'I¯',
|
|
|
|
'@=O' =>'O¯',
|
|
|
|
'@=U' =>'U¯',
|
|
|
|
'@=a' =>'a¯',
|
|
|
|
'@=e' =>'e¯',
|
|
|
|
'@=i' =>'i¯',
|
|
|
|
'@=o' =>'o¯',
|
|
|
|
'@=u' =>'u¯',
|
|
|
|
|
|
|
|
# other international characters and ligatures
|
|
|
|
#
|
|
|
|
'@L{}' =>'L', # Polish suppressed L/l
|
|
|
|
'@l{}' =>'l', # (currently unsupported)
|
|
|
|
'@AA{}' =>'Å',
|
|
|
|
'@aa{}' =>'å',
|
|
|
|
'@AE{}' =>'Æ', # ligatures
|
|
|
|
'@ae{}' =>'æ',
|
|
|
|
'@OE{}' =>'Œ',
|
|
|
|
'@oe{}' =>'œ',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@O{}' =>'Ø',
|
|
|
|
'@o{}' =>'ø',
|
|
|
|
'@ss{}' =>'ß',
|
2002-02-16 14:33:24 +00:00
|
|
|
|
|
|
|
'@error{}' =>'error-->', # glyphs used in examples
|
|
|
|
'@equiv{}' =>'≡',
|
|
|
|
'@expansion{}' =>'==>',
|
|
|
|
'@point{}' =>'-!-',
|
|
|
|
'@print{}' =>'-|',
|
|
|
|
'@result{}' =>'=>',
|
2002-02-18 09:04:56 +00:00
|
|
|
|
|
|
|
'@tab' =>'</entry><entry>',
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
);
|
|
|
|
|
2002-02-16 14:33:24 +00:00
|
|
|
# these are additional inline tags that always have {} following them.
|
|
|
|
# The replacement strings are triggers that they require some kind of
|
|
|
|
# programmatic control because they do strange things.
|
2002-02-02 04:55:52 +00:00
|
|
|
#
|
|
|
|
%specsubstitutions = (
|
2002-02-05 04:52:38 +00:00
|
|
|
'@anchor' =>'ANCHOR',
|
|
|
|
'@ref' =>'REF',
|
2002-02-21 10:52:32 +00:00
|
|
|
'@url' =>'UREF',
|
2002-02-05 04:52:38 +00:00
|
|
|
'@uref' =>'UREF',
|
|
|
|
'@xref' =>'XREF',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@pxref' =>'PXREF',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@inforef' =>'INFOREF',
|
2002-02-05 04:52:38 +00:00
|
|
|
'@kbd' =>'KBD',
|
2002-02-02 04:55:52 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
# These are special block wrapping tags. When we hit one of these,
|
|
|
|
# we simply wrap whatever comes between the (always paired) tags
|
|
|
|
# with a set of DocBook tags.
|
|
|
|
#
|
|
|
|
# Their handling is subtly different than the %tags.
|
|
|
|
# We don't just replace them with the DocBook tags, because we
|
|
|
|
# want any <para> tags to go inside them, not outside.
|
2002-03-10 15:06:43 +00:00
|
|
|
#
|
|
|
|
# Any existing para is closed first, as these are always paragraphs.
|
2002-02-02 04:55:52 +00:00
|
|
|
#
|
|
|
|
%blocks = (
|
2002-03-10 15:06:43 +00:00
|
|
|
# '@quotation' =>'<blockquote><literallayout>',
|
|
|
|
# '@end quotation' =>'</literallayout></blockquote>',
|
|
|
|
'@quotation' =>'<blockquote>',
|
|
|
|
'@end quotation' =>'</blockquote>',
|
2002-03-02 16:10:55 +00:00
|
|
|
# '@format' =>'<literallayout>',
|
|
|
|
# '@end format' =>'</literallayout>',
|
2002-02-02 04:55:52 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
# these are inline @-Commands which are replaced by a set of tags instead of one-for-one
|
|
|
|
# character substitution. Replacement is inline.
|
|
|
|
#
|
|
|
|
# there is also a special case, the "blank" tag, which does what you'd think.
|
|
|
|
# It removes the existing tag, but doesn't add the wrapper.
|
2002-02-16 14:33:24 +00:00
|
|
|
#
|
|
|
|
# Note that you can nest tags here by separating with commas.
|
2002-02-02 04:55:52 +00:00
|
|
|
#
|
2002-02-16 14:33:24 +00:00
|
|
|
# Examples: @code{foo} becomes <literal>foo</literal>.
|
|
|
|
# @footnote{foo} becomes <footnote><para>foo</para></footnote>.
|
2002-02-02 04:55:52 +00:00
|
|
|
#
|
|
|
|
%tags = (
|
2002-02-05 04:52:38 +00:00
|
|
|
'@acronym' =>'abbrev',
|
|
|
|
'@b' =>"emphasis role='bold'",
|
|
|
|
'@cite' =>'citetitle',
|
|
|
|
'@code' =>'literal',
|
|
|
|
'@command' =>'command',
|
|
|
|
'@dfn' =>"emphasis role='bold'",
|
2002-02-16 14:33:24 +00:00
|
|
|
'@dmn' =>'',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@dotless' =>'', # not yet supported, just discarded
|
|
|
|
'@dotless' =>'',
|
2002-02-05 04:52:38 +00:00
|
|
|
'@key' =>'keycap',
|
|
|
|
'@email' =>'email',
|
|
|
|
'@emph' =>'emphasis',
|
2002-02-18 09:04:56 +00:00
|
|
|
'@env' =>'envar',
|
2002-02-16 14:33:24 +00:00
|
|
|
'@footnote' =>'footnote, para',
|
2002-02-05 04:52:38 +00:00
|
|
|
'@file' =>'filename',
|
|
|
|
'@i' =>'emphasis',
|
2002-02-16 14:33:24 +00:00
|
|
|
'@option' =>'option',
|
2002-02-05 04:52:38 +00:00
|
|
|
'@samp' =>'literal',
|
|
|
|
'@sc' =>'',
|
2002-02-16 14:33:24 +00:00
|
|
|
'@strong' =>"emphasis role='bold'",
|
2002-02-05 04:52:38 +00:00
|
|
|
'@t' =>'programlisting',
|
2002-02-16 14:33:24 +00:00
|
|
|
'@r' =>'',
|
2002-02-07 07:34:47 +00:00
|
|
|
'@var' =>'literal',
|
2002-02-21 10:52:32 +00:00
|
|
|
'@verb' =>'literal',
|
2002-02-05 04:52:38 +00:00
|
|
|
'@w' =>'',
|
2002-02-02 04:55:52 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
# this is where definfoenclose definitions go, and they are processed last
|
|
|
|
#
|
2002-02-18 09:04:56 +00:00
|
|
|
# Note: Some built-in Texinfo accents can be seen as a kind of custom highlighting,
|
2002-02-16 14:33:24 +00:00
|
|
|
# since they cannot be displayed by a special glyph but are instead rendered
|
|
|
|
# by appending a character. Those glyphs are handled here.
|
|
|
|
#
|
|
|
|
# Note also that the "@" is not used here.
|
|
|
|
#
|
|
|
|
%definfos = (
|
|
|
|
'dotaccent' =>',.', # overdot accent
|
|
|
|
'H' =>',"', # Hungarian long umlaut
|
|
|
|
'ringaccent' =>',*', # ring accent
|
|
|
|
'tieaccent' =>',|', # tie-after accent
|
|
|
|
'u' =>',(', # breve accent
|
|
|
|
'ubaraccent' =>',_', # underbar accent
|
|
|
|
'udotaccent' =>'.,', # underdot accent
|
|
|
|
'v' =>',<', # tie-after accent
|
|
|
|
);
|
2002-02-02 04:55:52 +00:00
|
|
|
|
|
|
|
# and this is where macros are stored
|
|
|
|
#
|
|
|
|
$inmacro = 0;
|
|
|
|
$macro = "";
|
|
|
|
%macros = {};
|
|
|
|
$macroargs = "";
|
|
|
|
%macroargs = ();
|
|
|
|
$macrotext = "";
|
|
|
|
%macrotext = ();
|
|
|
|
|
2002-02-05 04:52:38 +00:00
|
|
|
%aliases = ();
|
2002-02-02 04:55:52 +00:00
|
|
|
|
|
|
|
##############################################################################
|
|
|
|
##############################################################################
|
|
|
|
##############################################################################
|
|
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
if ($ARGV[0] eq '') {
|
|
|
|
last;
|
2002-02-07 07:34:47 +00:00
|
|
|
} elsif (($ARGV[0] eq '-i') or ($ARGV[0] eq '--include')) {
|
|
|
|
shift(@ARGV);
|
|
|
|
if (($ARGV[0] eq 'HTML') or ($ARGV[0] eq 'TEX') or ($ARGV[0] eq 'INFO')) {
|
|
|
|
$outputtype = $ARGV[0];
|
|
|
|
} else {
|
|
|
|
&raiseerror("invalid include format: $ARGV[0]");
|
|
|
|
exit(1);
|
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
} elsif (($ARGV[0] eq '-f') or ($ARGV[0] eq '--file')) {
|
|
|
|
shift(@ARGV);
|
|
|
|
$requestedfile = $ARGV[0];
|
|
|
|
} elsif (($ARGV[0] eq '-o') or ($ARGV[0] eq '--output-to')) {
|
|
|
|
shift(@ARGV);
|
|
|
|
$outputfile = $ARGV[0];
|
2002-02-16 14:33:24 +00:00
|
|
|
} elsif (($ARGV[0] eq '-L') or ($ARGV[0] eq '--runon')) {
|
|
|
|
shift(@ARGV);
|
|
|
|
$maxrunonlines = $ARGV[0];
|
2002-02-02 04:55:52 +00:00
|
|
|
} elsif (($ARGV[0] eq '-l') or ($ARGV[0] eq '--log-to')) {
|
|
|
|
shift(@ARGV);
|
|
|
|
$logfile = $ARGV[0];
|
|
|
|
} elsif (($ARGV[0] eq '-e') or ($ARGV[0] eq '--max-errors')) {
|
|
|
|
shift(@ARGV);
|
|
|
|
$maxerrors = $ARGV[0];
|
2002-05-25 22:44:15 +00:00
|
|
|
} elsif (($ARGV[0] eq '-V') or ($ARGV[0] eq '--verbose')) {
|
2002-02-02 04:55:52 +00:00
|
|
|
$verbose++;
|
2002-05-25 22:44:15 +00:00
|
|
|
} elsif (($ARGV[0] eq '-v') or ($ARGV[0] eq '--version')) {
|
|
|
|
&version;
|
|
|
|
exit(0);
|
2002-02-02 04:55:52 +00:00
|
|
|
} elsif (($ARGV[0] eq '-h') or ($ARGV[0] eq '--help')) {
|
|
|
|
&usage;
|
|
|
|
} else {
|
|
|
|
&raiseerror("unrecognized option: $ARGV[0]\n");
|
|
|
|
$error = 1;
|
|
|
|
&usage;
|
|
|
|
}
|
|
|
|
shift(@ARGV);
|
|
|
|
}
|
|
|
|
|
|
|
|
# be sure to open the log file before trying to write any messages to it!
|
|
|
|
#
|
|
|
|
if ($logfile) {
|
|
|
|
open ($logfh, "> $logfile") or die "cannot write to log file $logfile.\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
$verbose = 3 if ($verbose > 3);
|
|
|
|
&message("verbose mode on.") if ($verbose == 1);
|
|
|
|
&message("debugging mode on.") if ($verbose ==2);
|
|
|
|
&message("insanity mode on.") if ($verbose ==3);
|
|
|
|
|
2002-02-07 07:34:47 +00:00
|
|
|
if ($outputtype eq 'HTML') {
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@ifhtml'} = 'DROPLINE';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifhtml'} = 'DROPLINE';
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@ifinfo'} = 'SEEKEND';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifinfo'} = 'DROPLINE';
|
|
|
|
$patterns{'@iftex'} = 'SEEKEND';
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@end iftex'} = 'DROPLINE';
|
|
|
|
$patterns{'@ifnothtml'} = 'SEEKEND';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifnothtml'} = 'DROPLINE';
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@ifnotinfo'} = 'DROPLINE';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifnotinfo'} = 'DROPLINE';
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@ifnottex'} = 'DROPLINE';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifnottex'} = 'DROPLINE';
|
|
|
|
&message("including HTML text") if ($verbose);
|
|
|
|
} elsif ($outputtype eq 'INFO') {
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@ifhtml'} = 'SEEKEND';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifhtml'} = 'DROPLINE';
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@ifinfo'} = 'DROPLINE';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifinfo'} = 'DROPLINE';
|
|
|
|
$patterns{'@iftex'} = 'SEEKEND';
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@end iftex'} = 'DROPLINE';
|
|
|
|
$patterns{'@ifnothtml'} = 'DROPLINE';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifnothtml'} = 'DROPLINE';
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@ifnotinfo'} = 'SEEKEND';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifnotinfo'} = 'DROPLINE';
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@ifnottex'} = 'DROPLINE';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifnottex'} = 'DROPLINE';
|
|
|
|
&message("including INFO text") if ($verbose);
|
|
|
|
} elsif ($outputtype eq 'TEX') {
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@ifhtml'} = 'SEEKEND';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifhtml'} = 'DROPLINE';
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@ifinfo'} = 'SEEKEND';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifinfo'} = 'DROPLINE';
|
|
|
|
$patterns{'@iftex'} = 'DROPLINE';
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@end iftex'} = 'DROPLINE';
|
|
|
|
$patterns{'@ifnothtml'} = 'DROPLINE';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifnothtml'} = 'DROPLINE';
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@ifnotinfo'} = 'DROPLINE';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifnotinfo'} = 'DROPLINE';
|
2002-02-18 09:04:56 +00:00
|
|
|
$patterns{'@ifnottex'} = 'SEEKEND';
|
2002-02-07 07:34:47 +00:00
|
|
|
$patterns{'@end ifnottex'} = 'DROPLINE';
|
|
|
|
&message("including TEX text") if ($verbose);
|
|
|
|
}
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
if ($outputfile) {
|
2002-02-05 04:52:38 +00:00
|
|
|
&message("output will go to $outputfile") if ($verbose);
|
2002-02-02 04:55:52 +00:00
|
|
|
open($outfh, "> $outputfile");
|
|
|
|
}
|
|
|
|
|
|
|
|
while (<DATA>) {
|
|
|
|
$template .= $_;
|
|
|
|
}
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
@substitutionkeys = sort {$b cmp $a} keys %substitutions;
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
&processfile ("$requestedfile");
|
|
|
|
|
|
|
|
&writefile;
|
|
|
|
close($outfh) if ($outputfile);
|
|
|
|
close($logfh) if ($logfile);
|
|
|
|
|
|
|
|
sub processfile {
|
|
|
|
my($filename,
|
|
|
|
$basename,
|
|
|
|
$path,
|
|
|
|
$ext,
|
|
|
|
$includefile,
|
|
|
|
$linenumber,
|
|
|
|
);
|
|
|
|
|
|
|
|
$macrolinecount = 0;
|
|
|
|
|
|
|
|
my $fh = new FileHandle;
|
|
|
|
|
|
|
|
$filename = @_[0];
|
2002-03-30 21:29:39 +00:00
|
|
|
$filename = '' unless ($filename);
|
2002-02-02 04:55:52 +00:00
|
|
|
|
|
|
|
($basename, $path, $ext) = fileparse($filename);
|
|
|
|
&message("processing $filename") if ($verbose);
|
|
|
|
$linenumber = 0;
|
|
|
|
|
2002-03-30 21:29:39 +00:00
|
|
|
if ($filename) {
|
|
|
|
open $fh, "<$filename" or raiseerror("cannot open $filename\n");
|
|
|
|
} else {
|
|
|
|
$fh = STDIN;
|
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
LINE: while ($line = <$fh>) {
|
|
|
|
chomp($line);
|
|
|
|
|
|
|
|
$linenumber++;
|
|
|
|
$currentfile = $filename;
|
|
|
|
$currentline = $linenumber;
|
|
|
|
|
|
|
|
if ($seekend) {
|
|
|
|
$seekend = '' if ($line =~ /$seekend/);
|
|
|
|
next LINE;
|
|
|
|
}
|
|
|
|
|
|
|
|
&message("LINE $currentline: $line") if ($verbose > 1);
|
|
|
|
|
2002-02-19 05:02:23 +00:00
|
|
|
&cleanline;
|
2002-02-21 10:52:32 +00:00
|
|
|
&markspecial; # hide @@, @{, @} to ease parsing
|
2002-02-19 05:02:23 +00:00
|
|
|
$originalline = $line; # must be cleaned but not trimmed!
|
|
|
|
$trimline;
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
# We have to handle some @-commands on the line when they appear,
|
|
|
|
# even if waiting for some wrapper command to complete:
|
|
|
|
#
|
|
|
|
# e.g., @footer{foo bar
|
|
|
|
# @cindex baz
|
|
|
|
# blah blah}
|
2002-02-19 05:02:23 +00:00
|
|
|
# and @comment, @c
|
|
|
|
#
|
|
|
|
if (($line =~ /\@c\b/) or ($line =~ /\@comment\b/)) {
|
|
|
|
&comment;
|
|
|
|
}
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
($pattern, $action) = &matchpattern();
|
|
|
|
if ($action eq 'DROPLINE') {
|
|
|
|
next LINE;
|
|
|
|
}
|
|
|
|
|
2002-02-05 04:52:38 +00:00
|
|
|
# keep reading until we have only complete tags
|
|
|
|
#
|
2002-02-02 04:55:52 +00:00
|
|
|
if ($saveline) {
|
|
|
|
$line = $saveline . ' ' . $line;
|
|
|
|
$saveline = '';
|
|
|
|
&message("line restored, line: $line") if ($verbose > 1);
|
|
|
|
}
|
|
|
|
unless (&bracketsmatch($line)) {
|
|
|
|
&message("bracket mismatch") if ($verbose > 2);
|
|
|
|
$saveline = $line;
|
|
|
|
next LINE;
|
|
|
|
}
|
|
|
|
|
2002-02-21 10:52:32 +00:00
|
|
|
if (scalar @literal) {
|
|
|
|
&message("checking for $literalendtag") if ($verbose > 2);
|
|
|
|
if ($line =~ /$literalendtag/) {
|
|
|
|
&message("End literal block") if ($verbose > 2);
|
|
|
|
&closeliteralblock;
|
|
|
|
next LINE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
if ($line =~ /^\@include/) {
|
|
|
|
$includefile = $line;
|
|
|
|
$includefile =~ s/^\@include\s+//;
|
|
|
|
$includefile = $path . $includefile;
|
|
|
|
$line = '';
|
|
|
|
if (-e $includefile) {
|
|
|
|
&message("including $includefile") if ($verbose);
|
|
|
|
&processfile ("$includefile");
|
|
|
|
} else {
|
|
|
|
&raiseerror("include file $includefile not found.");
|
|
|
|
}
|
|
|
|
} elsif ($inmacro) {
|
|
|
|
($pattern, $action) = &matchpattern();
|
|
|
|
if ($action eq 'SEEKEND') {
|
|
|
|
$seekend = $pattern;
|
|
|
|
$seekend =~ s/\@/\@end /;
|
|
|
|
next LINE;
|
|
|
|
} elsif ($action eq 'DROPLINE') {
|
|
|
|
next LINE;
|
2002-02-18 09:04:56 +00:00
|
|
|
} elsif ($action eq 'DROP2') {
|
|
|
|
$line =~ s/\@\w+\s+\w+\s*//;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
if ($line =~ /\@end\s+macro/) {
|
|
|
|
#save macro
|
|
|
|
$macroargs{$macro} = $macroargs;
|
|
|
|
$macrotext{$macro} = $macrotext;
|
|
|
|
&message("macro name: $macro args: $macroargs text: $macrotext") if ($verbose > 2);
|
|
|
|
$inmacro = 0;
|
|
|
|
$macroargs = '';
|
|
|
|
$macrotext = '';
|
|
|
|
$macrolinecount = 0;
|
|
|
|
} elsif ($line =~ /\@quote-arg/) {
|
|
|
|
} else {
|
|
|
|
&message("macro line: $line") if ($verbose > 2);
|
|
|
|
$macrotext .= $line;
|
|
|
|
$macrolinecount++;
|
|
|
|
if ($macrolinecount >= 10) {
|
2002-02-16 14:33:24 +00:00
|
|
|
&raiseerror("runon macro");
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
2002-02-21 10:52:32 +00:00
|
|
|
} elsif ($inmenu) {
|
|
|
|
&message("inmenu: $line");
|
|
|
|
if ($line =~ /\@end menu/) {
|
|
|
|
&closemenu;
|
|
|
|
} else {
|
|
|
|
&menuitem;
|
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
} else {
|
2002-02-21 10:52:32 +00:00
|
|
|
if ($suppressconversion) {
|
|
|
|
$line = $originalline;
|
|
|
|
$pattern = '';
|
|
|
|
$action = '';
|
|
|
|
} else {
|
|
|
|
($pattern, $action) = &matchblock();
|
|
|
|
if ($action) {
|
2002-03-10 15:06:43 +00:00
|
|
|
&message("replacing block with $action") if ($verbose > 2);
|
2002-02-21 10:52:32 +00:00
|
|
|
&closepara;
|
|
|
|
$buf .= $action;
|
|
|
|
next LINE;
|
|
|
|
}
|
|
|
|
($pattern, $action) = &matchpattern();
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
2002-02-21 10:52:32 +00:00
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
if ($action eq 'DROPLINE') {
|
|
|
|
next LINE;
|
|
|
|
} else {
|
2002-05-25 15:32:11 +00:00
|
|
|
&doaction;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
2002-05-25 15:32:11 +00:00
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
close($fh);
|
|
|
|
}
|
|
|
|
|
2002-05-25 15:32:11 +00:00
|
|
|
sub doaction {
|
2002-05-25 22:44:15 +00:00
|
|
|
if ($action eq 'DROP2') {
|
|
|
|
$line =~ s/\@\w+\s+\w+\s*//;
|
|
|
|
&writeconverted;
|
|
|
|
} elsif ($action eq 'SEEKEND') {
|
|
|
|
$seekend = $pattern;
|
|
|
|
$seekend =~ s/\@/\@end /;
|
|
|
|
} elsif ($action eq 'LITERALBLOCK') {
|
|
|
|
&literalblock;
|
|
|
|
} elsif ($action eq 'ALIAS') {
|
|
|
|
&alias;
|
|
|
|
} elsif ($action eq 'MACRO') {
|
|
|
|
¯o;
|
|
|
|
} elsif ($action eq 'META') {
|
|
|
|
&meta;
|
|
|
|
} elsif ($action eq 'NODE') {
|
|
|
|
&node;
|
|
|
|
} elsif ($action eq 'MENU') {
|
|
|
|
&menu;
|
|
|
|
} elsif ($action eq 'APPENDIX') {
|
|
|
|
$line =~ s/^\@\w+\s+//;
|
|
|
|
&convertinline;
|
|
|
|
&appendix($line);
|
|
|
|
} elsif ($action eq 'SECT1') {
|
|
|
|
$line =~ s/^\@\w+\s+//;
|
|
|
|
&convertinline;
|
|
|
|
§1($line);
|
|
|
|
} elsif ($action eq 'SECT2') {
|
|
|
|
$line =~ s/^\@\w+\s+//;
|
|
|
|
&convertinline;
|
|
|
|
§2($line);
|
|
|
|
} elsif ($action eq 'SECT3') {
|
|
|
|
$line =~ s/^\@\w+\s+//;
|
|
|
|
&convertinline;
|
|
|
|
§3($line);
|
|
|
|
} elsif ($action eq 'SECT4') {
|
|
|
|
$line =~ s/^\@\w+\s+//;
|
|
|
|
&convertinline;
|
|
|
|
§4($line);
|
|
|
|
} elsif ($action eq 'CINDEX') {
|
|
|
|
$line =~ s/^\@\w+\s+//;
|
|
|
|
&convertinline;
|
|
|
|
&indexterm($line);
|
|
|
|
} elsif ($action eq 'PARA') {
|
|
|
|
&closeformalpara;
|
|
|
|
¶
|
|
|
|
} elsif ($action eq 'DEFFN') {
|
|
|
|
&deffn;
|
|
|
|
} elsif ($action eq 'ORDEREDLIST') {
|
|
|
|
&orderedlist;
|
|
|
|
} elsif ($action eq 'ORDEREDLISTEND') {
|
|
|
|
&closeorderedlist;
|
|
|
|
} elsif ($action eq 'ITEMIZEDLIST') {
|
|
|
|
&itemizedlist;
|
|
|
|
} elsif ($action eq 'ITEMIZEDLISTEND') {
|
|
|
|
&closeitemizedlist;
|
|
|
|
} elsif ($action eq 'ITEM') {
|
|
|
|
&item;
|
|
|
|
&writeconverted;
|
|
|
|
} elsif ($action eq 'TABLE') {
|
|
|
|
&table;
|
|
|
|
$line =~ s/^\@\w+\s+//;
|
|
|
|
$tableformat[-1] = $line;
|
|
|
|
&message("table format: $tableformat[-1]") if ($verbose > 2);
|
|
|
|
$infirstcol[-1] = 0;
|
|
|
|
} elsif ($action eq 'MULTITABLE') {
|
|
|
|
&multitable;
|
|
|
|
} elsif ($action eq 'TABLEEND') {
|
|
|
|
&closetable;
|
|
|
|
} elsif ($action eq 'INDEX') {
|
|
|
|
&message("indexing not yet supported") if ($verbose > 1);
|
|
|
|
} elsif ($action eq 'DEFINFOENCLOSE') {
|
|
|
|
&definfoenclose;
|
|
|
|
} elsif ($action eq 'SET') {
|
|
|
|
&set;
|
|
|
|
} elsif ($action eq 'CLEAR') {
|
|
|
|
&clear;
|
|
|
|
} elsif ($action eq 'IFSET') {
|
|
|
|
$seekend = '\@end ifset' unless (&ifset());
|
|
|
|
} elsif ($action eq 'IFCLEAR') {
|
|
|
|
$seekend = '\@end ifclear' if (&ifset());
|
|
|
|
} elsif ($action eq 'BYE') {
|
|
|
|
&closesect1;
|
|
|
|
last;
|
|
|
|
} elsif ($action eq 'ERROR') {
|
|
|
|
&raiseerror("Hit ERROR tag with $pattern on $line");
|
|
|
|
} elsif ($action eq '') {
|
|
|
|
if ($nest[-1] eq 'table') { # multitables just write the line
|
|
|
|
&tableline;
|
|
|
|
}
|
|
|
|
if ($suppressconversion) {
|
|
|
|
&writeline;
|
|
|
|
} else {
|
|
|
|
&writeconverted;
|
|
|
|
}
|
2002-05-25 15:32:11 +00:00
|
|
|
} else {
|
2002-05-25 22:44:15 +00:00
|
|
|
&raiseerror("Unknown action: $action on command $pattern");
|
2002-05-25 15:32:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-02-05 04:52:38 +00:00
|
|
|
sub cleanline {
|
2002-02-19 05:02:23 +00:00
|
|
|
$line =~ s/&/&/g; # do first, before writing new amps
|
|
|
|
$line =~ s/\</</g;
|
|
|
|
$line =~ s/\>/>/g;
|
|
|
|
$line =~ s/\x0C//;
|
|
|
|
$line =~ s/\xA0/ /;
|
|
|
|
$line =~ s/\xD7//;
|
2002-03-10 15:06:43 +00:00
|
|
|
$line =~ s/\xD8/Ö/;
|
|
|
|
$line =~ s/\xDF/ß/;
|
2002-02-19 05:02:23 +00:00
|
|
|
$line =~ s/\xF6/ö/;
|
2002-02-21 10:52:32 +00:00
|
|
|
$line =~ s/\xE4/ä/;
|
2002-02-19 05:02:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub writeabstract {
|
|
|
|
if ($inabstract) {
|
|
|
|
$inabstract = 0;
|
|
|
|
&message("copying meta-data to docbook") if ($verbose);
|
|
|
|
$template =~ s/%%TITLE/$title/;
|
2002-05-25 15:32:11 +00:00
|
|
|
$lang =~ s/\s+/q/g;
|
|
|
|
$template =~ s/%%LANG/$lang/;
|
2002-02-19 05:02:23 +00:00
|
|
|
if ($buf) {
|
|
|
|
$template =~ s/%%ABSTRACT/$buf/;
|
|
|
|
} else {
|
|
|
|
$template =~ s/\<abstract\>%%ABSTRACT\<\/abstract\>//s;
|
|
|
|
}
|
|
|
|
print $outfh $template . "\n";
|
|
|
|
$buf = "";
|
|
|
|
}
|
2002-02-05 04:52:38 +00:00
|
|
|
}
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
sub writefile {
|
|
|
|
&closeappendix;
|
2002-02-05 04:52:38 +00:00
|
|
|
print $outfh $buf;
|
2002-02-02 04:55:52 +00:00
|
|
|
print $outfh '</article>'. "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
####################
|
|
|
|
# PATTERN MATCHING #
|
|
|
|
####################
|
|
|
|
|
|
|
|
# this is for beginning-of-line @-commands
|
|
|
|
#
|
|
|
|
sub matchpattern {
|
2002-02-07 07:34:47 +00:00
|
|
|
$pattern = "";
|
2002-02-02 04:55:52 +00:00
|
|
|
foreach $key (keys %patterns) {
|
2002-02-16 14:33:24 +00:00
|
|
|
$pattern = quotemeta($key) . '\b';
|
2002-02-07 07:34:47 +00:00
|
|
|
if ($line =~ /^$pattern\b/) {
|
|
|
|
return ($pattern, $patterns{$key});
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return ('', '');
|
|
|
|
}
|
|
|
|
|
|
|
|
# this is for special wrapped blocks, like blockquotes
|
|
|
|
#
|
|
|
|
sub matchblock {
|
|
|
|
foreach $key (keys %blocks) {
|
2002-02-18 09:04:56 +00:00
|
|
|
$pattern = quotemeta($key);
|
|
|
|
if ($line =~ /$pattern/) {
|
|
|
|
&message("matched block $pattern") if ($verbose > 2);
|
|
|
|
return ($pattern, $blocks{$key}) unless ($line =~ /$pattern\w/);
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-03-10 15:06:43 +00:00
|
|
|
# inline processing
|
2002-02-02 04:55:52 +00:00
|
|
|
#
|
|
|
|
sub convertinline {
|
2002-02-05 04:52:38 +00:00
|
|
|
TAG: while ($line =~ /\@\w+\{[^\{]*?\}/) {
|
|
|
|
|
|
|
|
$command = $line;
|
|
|
|
$command =~ s/.*(\@\w+\{[^{]*?\}).*/\1/;
|
|
|
|
$tag = $command;
|
|
|
|
$tag =~ s/(.*)\{.*/\1/;
|
|
|
|
$tagplain = $tag;
|
|
|
|
$tagplain =~ s/\@//;
|
|
|
|
$contents = $command;
|
|
|
|
$contents =~ s/.*\{(.*)\}/\1/;
|
2002-02-21 14:04:05 +00:00
|
|
|
&message("CMDLINE: $line") if ($verbose > 2);
|
2002-02-18 09:04:56 +00:00
|
|
|
&message("CMD: $command, tag: $tag, tagplain: $tagplain, contents: $contents") if ($verbose > 2);
|
2002-02-05 04:52:38 +00:00
|
|
|
|
2002-05-25 22:44:15 +00:00
|
|
|
# If we're in a table's first column, and this column already contains
|
|
|
|
# the same tag, remove the internal tag.
|
|
|
|
# Otherwise, we wind up with nested literals, which DocBook disallows.
|
2002-03-10 15:06:43 +00:00
|
|
|
#
|
|
|
|
if (scalar @tableformat) {
|
2002-03-10 16:32:16 +00:00
|
|
|
if (($infirstcol[-1]) and ($tableformat[-1] eq $tag)) {
|
2002-05-25 22:44:15 +00:00
|
|
|
&message("not doubly wrapping tag $tag, removing the nested one") if ($verbose >2);
|
|
|
|
|
|
|
|
$contents =~ s/\<$tag\>//;
|
|
|
|
$contents =~ s/\<\/$tag\>//;
|
|
|
|
|
|
|
|
#$replacement = $contents;
|
|
|
|
#&replaceinline;
|
|
|
|
#next TAG;
|
2002-03-10 15:06:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
# substitutions (we only want to catch @{} type tags here)
|
2002-02-05 04:52:38 +00:00
|
|
|
#
|
2002-02-18 09:04:56 +00:00
|
|
|
if (exists $substitutions{$tag . '{}'}) {
|
2002-02-15 14:30:00 +00:00
|
|
|
&message("matched character substitution $tag") if ($verbose >2);
|
2002-02-18 09:04:56 +00:00
|
|
|
$replacement = $substitutions{$tag . '{}'};
|
2002-02-05 04:52:38 +00:00
|
|
|
&replaceinline;
|
|
|
|
next TAG;
|
|
|
|
}
|
|
|
|
|
|
|
|
# macros
|
|
|
|
#
|
|
|
|
if (exists $macros{$tagplain}) {
|
2002-02-15 14:30:00 +00:00
|
|
|
&message("matched macro $tagplain") if ($verbose >2);
|
2002-02-05 04:52:38 +00:00
|
|
|
$macro = $macros{$tagplain};
|
|
|
|
$macroargs = "\\\\" . $macroargs{$tagplain} . "\\\\";
|
|
|
|
$macrotext = $macrotext{$tagplain};
|
|
|
|
|
|
|
|
$macroarg = $command;
|
|
|
|
$macroarg =~ s/^.*?\@$macro\{//;
|
|
|
|
$macroarg =~ s/\}.*?$//;
|
|
|
|
$macrotext =~ s/\@$macro\{([^\{]*?)\}/$macroarg/;
|
|
|
|
$macrotext =~ s/$macroargs/$macroarg/g;
|
|
|
|
$replacement = $macrotext;
|
|
|
|
&replaceinline;
|
|
|
|
next TAG;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
2002-02-05 04:52:38 +00:00
|
|
|
# special character substitutions
|
|
|
|
#
|
|
|
|
if (exists $specsubstitutions{$tag}) {
|
2002-02-15 14:30:00 +00:00
|
|
|
&message("matched special substitution $tag") if ($verbose >2);
|
2002-02-05 04:52:38 +00:00
|
|
|
$replacement = $specsubstitutions{$tag};
|
|
|
|
&replacespecsubst;
|
|
|
|
&replaceinline;
|
|
|
|
next TAG;
|
|
|
|
}
|
|
|
|
|
|
|
|
# docbook wrapper tags
|
|
|
|
#
|
|
|
|
if (exists $tags{$tag}) {
|
2002-02-15 14:30:00 +00:00
|
|
|
&message("matched docbook wrapper tag $tag") if ($verbose >2);
|
2002-02-16 14:33:24 +00:00
|
|
|
@dbtags = split(',', $tags{$tag});
|
|
|
|
$dbopen = '';
|
|
|
|
$dbclose = '';
|
|
|
|
|
|
|
|
foreach $dbtag (@dbtags) {
|
|
|
|
$dbtag = &trim($dbtag);
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
# Texinfo allows nexted literals, DocBook does not.
|
2002-02-16 14:33:24 +00:00
|
|
|
#
|
2002-02-18 09:04:56 +00:00
|
|
|
if (($dbtag eq 'programlisting')
|
|
|
|
or ($dbtag eq 'literal')
|
|
|
|
or ($dbtag eq 'filename')
|
|
|
|
or ($dbtag eq 'option')) {
|
|
|
|
$contents =~ s/\<literal\>//g;
|
|
|
|
$contents =~ s/\<\/literal\>//g;
|
2002-03-10 15:06:43 +00:00
|
|
|
$contents =~ s/\<programlisting\>//g;
|
|
|
|
$contents =~ s/\<\/programlisting\>//g;
|
|
|
|
&message("removed inline literals: $contents") if ($verbose > 2);
|
2002-02-18 09:04:56 +00:00
|
|
|
}
|
2002-02-16 14:33:24 +00:00
|
|
|
|
|
|
|
($tag, $attributes) = split(/ /, $dbtag);
|
2002-02-05 04:52:38 +00:00
|
|
|
if ($attributes) {
|
2002-02-16 14:33:24 +00:00
|
|
|
$dbopen .= "\<$tag $attributes\>";
|
2002-02-05 04:52:38 +00:00
|
|
|
} else {
|
2002-02-16 14:33:24 +00:00
|
|
|
$dbopen .= "\<$tag\>";
|
2002-02-05 04:52:38 +00:00
|
|
|
}
|
2002-02-16 14:33:24 +00:00
|
|
|
$dbclose = "\<\/$tag\>" . $dbclose;
|
2002-02-05 04:52:38 +00:00
|
|
|
}
|
2002-02-16 14:33:24 +00:00
|
|
|
$replacement = $dbopen . $contents . $dbclose;
|
2002-03-10 15:06:43 +00:00
|
|
|
|
|
|
|
# Texinfo allows nexted literals, DocBook does not.
|
|
|
|
#
|
|
|
|
if (scalar @literal) {
|
|
|
|
$replacement =~ s/\<literal\>//g;
|
|
|
|
$replacement =~ s/\<\/literal\>//g;
|
|
|
|
$replacement =~ s/\<programlisting\>//g;
|
|
|
|
$replacement =~ s/\<\/programlisting\>//g;
|
|
|
|
&message("removed literal tags literals: $replacement") if ($verbose > 2);
|
|
|
|
}
|
|
|
|
|
2002-02-05 04:52:38 +00:00
|
|
|
&replaceinline;
|
|
|
|
next TAG;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
2002-02-05 04:52:38 +00:00
|
|
|
if (exists $definfos{$tagplain}){
|
2002-02-15 14:30:00 +00:00
|
|
|
&message("matched definfo $tagplain") if ($verbose >2);
|
2002-02-05 04:52:38 +00:00
|
|
|
$action = $definfos{$tagplain};
|
|
|
|
($prefix, $suffix) = split(/,/,$action);
|
|
|
|
$replacement = $prefix . $contents . $suffix;
|
|
|
|
&message("definfo prefix: $prefix, suffix: $suffix, contents: $contents") if ($verbose > 1);
|
|
|
|
&replaceinline;
|
|
|
|
next TAG;
|
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
|
2002-02-05 04:52:38 +00:00
|
|
|
if (exists $setvalues{$contents}) {
|
2002-02-15 14:30:00 +00:00
|
|
|
&message("matched set value $contents") if ($verbose > 2);
|
2002-02-05 04:52:38 +00:00
|
|
|
$replacement = $setvalues{$contents};
|
|
|
|
&replaceinline;
|
|
|
|
next TAG;
|
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
|
2002-02-05 04:52:38 +00:00
|
|
|
if (exists $aliases{$tag}) {
|
2002-02-15 14:30:00 +00:00
|
|
|
&message("matched alias $tag") if ($verbose >2);
|
2002-02-05 04:52:38 +00:00
|
|
|
$replacement = $aliases{$tag} . '{' . $contents . '}';
|
|
|
|
&replaceinline;
|
|
|
|
next TAG;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
2002-02-05 04:52:38 +00:00
|
|
|
|
|
|
|
&raiseerror("cannot resolve $command");
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
2002-02-18 09:04:56 +00:00
|
|
|
|
|
|
|
# character-level substitutions.
|
|
|
|
# must come last, so tags like @samp{} don't have the @s replaced
|
|
|
|
# with a space, etc.
|
|
|
|
#
|
|
|
|
# This uses a presorted array of keys in descending order,
|
|
|
|
# so we see @ss before @s, etc.
|
|
|
|
#
|
2002-02-21 14:04:05 +00:00
|
|
|
foreach $key (@substitutionkeys) {
|
2002-02-18 09:04:56 +00:00
|
|
|
$pattern = quotemeta($key);
|
2002-02-21 14:04:05 +00:00
|
|
|
if ($line =~ /$pattern/) {
|
|
|
|
&message("matched character code: $key") if ($verbose > 2);
|
|
|
|
$line =~ s/$pattern/$substitutions{$key}/g;
|
|
|
|
}
|
2002-02-18 09:04:56 +00:00
|
|
|
}
|
2002-02-21 10:52:32 +00:00
|
|
|
|
|
|
|
# unusual stuff to deal with
|
|
|
|
#
|
2002-03-10 15:06:43 +00:00
|
|
|
# @\n is sometimes entered when the user meant @(space).
|
|
|
|
# Texinfo handles it, so we have to.
|
|
|
|
#
|
2002-02-21 10:52:32 +00:00
|
|
|
$line =~ s/\@$/ /;
|
2002-02-05 04:52:38 +00:00
|
|
|
|
2002-03-10 15:06:43 +00:00
|
|
|
# Remove <> from inside <email></email> tags, since DocBook stylesheets
|
|
|
|
# generally add them back in when generating output.
|
|
|
|
#
|
|
|
|
$line =~ s/\<email\><(.*?)>\<\/email\>/\<email\>$1\<\/email\>/g;
|
|
|
|
|
2002-05-25 15:32:11 +00:00
|
|
|
# We take care in case there's a matching block (it could ocurred
|
|
|
|
# because of the expansion of a macro or an alias)
|
|
|
|
|
|
|
|
($pattern, $action) = &matchpattern();
|
|
|
|
&doaction if ($action);
|
|
|
|
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
# We should have found *all* @-commands by now.
|
|
|
|
# If any are still hanging around, we have a problem.
|
|
|
|
#
|
|
|
|
if ($line =~ /\@/) {
|
|
|
|
&raiseerror("Unrecognized @-command in $line");
|
|
|
|
}
|
2002-02-16 14:33:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub markspecial {
|
2002-02-21 10:52:32 +00:00
|
|
|
my $pattern1 = '';
|
|
|
|
my $pattern2 = '';
|
|
|
|
my $delimiter = '';
|
|
|
|
my $delimiterpattern = '';
|
|
|
|
my $contents = '';
|
|
|
|
my $contentspattern = '';
|
|
|
|
my $newcontents = '';
|
|
|
|
my $start = '';
|
|
|
|
my $end = '';
|
|
|
|
|
|
|
|
$line =~ s/\@\@/DCM_AT/g;
|
|
|
|
$line =~ s/\@\{/DCM_LB/g;
|
|
|
|
$line =~ s/\@\}/DCM_RB/g;
|
2002-02-21 14:04:05 +00:00
|
|
|
$line =~ s/\@\,{c\}/DCM_CD/g;
|
2002-02-21 10:52:32 +00:00
|
|
|
|
|
|
|
# special handling for the @verb{} command, which contains
|
|
|
|
# within it special characters which are NOT to be interpreted.
|
|
|
|
# rather than handle such a strange case, we make it simple by
|
|
|
|
# going the long way around and escaping everything
|
|
|
|
#
|
|
|
|
unless ($suppressconversion) {
|
|
|
|
while ($line =~ /\@verb\{/) {
|
|
|
|
$delimiter = $line;
|
|
|
|
$delimiter =~ s/.*?\@verb\{//;
|
|
|
|
$delimiter =~ s/(.).*/$1/;
|
|
|
|
&message("delimiter: $delimiter") if ($verbose > 2);
|
|
|
|
$delimiterpattern = quotemeta($delimiter);
|
|
|
|
&message("delimiterpattern: $delimiterpattern") if ($verbose > 2);
|
|
|
|
$contents = $line;
|
|
|
|
$pattern1 = '.*\@verb\{' . quotemeta($delimiter);
|
|
|
|
&message("pattern1: $pattern1") if ($verbose > 2);
|
|
|
|
$contents =~ s/$pattern1//;
|
|
|
|
$pattern2 = quotemeta($delimiter) . '\}.*';
|
|
|
|
&message("pattern2: $pattern2") if ($verbose > 2);
|
|
|
|
$contents =~ s/$pattern1//;
|
|
|
|
&message("contents: $contents") if ($verbose > 2);
|
|
|
|
$contents =~ s/$pattern2//;
|
|
|
|
&message("contents: $contents") if ($verbose > 2);
|
|
|
|
$newcontents = $contents;
|
|
|
|
$newcontents =~ s/\@/\@\@/g;
|
|
|
|
$newcontents =~ s/\{/\@\{/g;
|
|
|
|
$newcontents =~ s/\}/\@\}/g;
|
|
|
|
&message("newcontents: $newcontents") if ($verbose > 2);
|
|
|
|
$contentspattern = quotemeta($contents);
|
|
|
|
&message("contentspattern: $contentspattern") if ($verbose > 2);
|
|
|
|
$start = $line;
|
|
|
|
$start =~ s/$pattern2.*//;
|
|
|
|
$start =~ s/$delimiterpattern$contentspattern$//;
|
|
|
|
$start =~ s/\@verb/DCM_VERB/;
|
|
|
|
&message("start: $start") if ($verbose > 2);
|
|
|
|
$end = $line;
|
|
|
|
$end =~ s/.*$pattern1$contentspattern$delimiterpattern//;
|
|
|
|
&message("end: $end") if ($verbose > 2);
|
|
|
|
$line = $start . $newcontents . $end;
|
|
|
|
&message("line: $line") if ($verbose > 2);
|
|
|
|
}
|
|
|
|
$line =~ s/DCM_VERB/\@verb/g;
|
|
|
|
|
|
|
|
}
|
2002-02-21 14:04:05 +00:00
|
|
|
|
|
|
|
# We do this twice in case one of these was inside a @verb statement
|
|
|
|
#
|
2002-02-16 14:33:24 +00:00
|
|
|
$line =~ s/\@\@/DCM_AT/g;
|
|
|
|
$line =~ s/\@\{/DCM_LB/g;
|
|
|
|
$line =~ s/\@\}/DCM_RB/g;
|
2002-02-21 14:04:05 +00:00
|
|
|
$line =~ s/\@\,{c\}/DCM_CD/g;
|
2002-02-16 14:33:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub unmarkspecial {
|
2002-02-21 10:52:32 +00:00
|
|
|
$_[0] =~ s/DCM_AT/\@\@/gi;
|
|
|
|
$_[0] =~ s/DCM_LB/\@\{/gi;
|
|
|
|
$_[0] =~ s/DCM_RB/\@\}/gi;
|
2002-02-21 14:04:05 +00:00
|
|
|
$_[0] =~ s/DCM_CD/\@\{c\}/gi;
|
2002-02-19 05:02:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub normalizespecial {
|
2002-02-21 10:52:32 +00:00
|
|
|
$_[0] =~ s/DCM_AT/\@/gi;
|
|
|
|
$_[0] =~ s/DCM_LB/\{/gi;
|
|
|
|
$_[0] =~ s/DCM_RB/\}/gi;
|
2002-02-21 14:04:05 +00:00
|
|
|
$_[0] =~ s/DCM_CD/¸/gi;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
2002-02-05 04:52:38 +00:00
|
|
|
sub replaceinline {
|
|
|
|
&message("replacing $command with $replacement") if ($verbose > 1);
|
|
|
|
$command = quotemeta($command);
|
|
|
|
$line =~ s/$command/$replacement/;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub replacespecsubst {
|
2002-02-18 09:04:56 +00:00
|
|
|
my $link = '';
|
|
|
|
my $linktitle = '';
|
2002-02-05 04:52:38 +00:00
|
|
|
my $keystring;
|
|
|
|
my @keycombos;
|
|
|
|
my @keycaps;
|
|
|
|
my $mykeys;
|
|
|
|
|
|
|
|
if ($replacement eq 'REF') {
|
2002-02-18 09:04:56 +00:00
|
|
|
$replacement = &crossref();
|
2002-02-07 07:34:47 +00:00
|
|
|
} elsif ($replacement eq 'PXREF') {
|
2002-02-18 09:04:56 +00:00
|
|
|
$replacement = "see " . &crossref();
|
2002-02-05 04:52:38 +00:00
|
|
|
} elsif ($replacement eq 'UREF') {
|
2002-02-18 09:04:56 +00:00
|
|
|
($link, $linktitle) = split(/,/, $contents);
|
2002-02-02 04:55:52 +00:00
|
|
|
$link = &trim($link);
|
2002-02-18 09:04:56 +00:00
|
|
|
$linktitle = &trim($linktitle);
|
|
|
|
$linktitle = $link unless ($linktitle);
|
|
|
|
$replacement = "\<ulink url='$link'\>$linktitle\<\/ulink\>";
|
|
|
|
&message("ulink: $link, linktitle: $linktitle") if ($verbose > 2);
|
2002-02-05 04:52:38 +00:00
|
|
|
} elsif ($replacement eq 'XREF') {
|
2002-02-18 09:04:56 +00:00
|
|
|
$replacement = "See " . &crossref();
|
|
|
|
} elsif ($replacement eq 'INFOREF') {
|
|
|
|
$replacement = "See " . &inforef();
|
2002-02-05 04:52:38 +00:00
|
|
|
} elsif ($replacement eq 'ANCHOR') {
|
|
|
|
$link = $contents;
|
|
|
|
$link = &anchorfix($link);
|
|
|
|
$replacement = "<anchor id='$link'\/\>";
|
|
|
|
} elsif ($replacement eq 'KBD') {
|
|
|
|
$keystring = $contents;
|
2002-02-18 09:04:56 +00:00
|
|
|
|
|
|
|
# nested literals not allowed in DocBook
|
|
|
|
#
|
|
|
|
$keystring =~ s/\<literal\>//g;
|
|
|
|
$keystring =~ s/\<\/literal\>//g;
|
|
|
|
|
|
|
|
# I found there is at least one case where <keycap> is already here:
|
2002-02-16 09:24:36 +00:00
|
|
|
# @kbd{gTop<keycap>RET</keycap>}, in the info manual.
|
2002-02-15 14:30:00 +00:00
|
|
|
# If we have those, throw away the keycap tags and hyphenate,
|
|
|
|
# so we can keycombo properly.
|
|
|
|
#
|
|
|
|
$keystring =~ s/\<keycap\>/-/g;
|
|
|
|
$keystring =~ s/\<\/keycap\>/-/g;
|
|
|
|
$keystring =~ s/^-+//g;
|
|
|
|
$keystring =~ s/-+$//g;
|
|
|
|
$keystring =~ s/-+\s+/-/g;
|
|
|
|
$keystring =~ s/\s+-+/-/g;
|
|
|
|
|
2002-02-05 04:52:38 +00:00
|
|
|
@keycombos = split(/\s+/, $keystring);
|
|
|
|
foreach $keycombo (@keycombos) {
|
2002-02-07 07:34:47 +00:00
|
|
|
&message("keycombo: $keycombo") if ($verbose > 2);
|
2002-02-15 14:30:00 +00:00
|
|
|
@keycaps = split(/-/, $keycombo);
|
|
|
|
if (scalar @keycaps > 1) {
|
|
|
|
&message("making keycombo") if ($verbose > 2);
|
2002-02-05 04:52:38 +00:00
|
|
|
$mykeys .= "\<keycombo action='simul'\>";
|
|
|
|
foreach $keycap (@keycaps) {
|
|
|
|
$mykeys .= "\<keycap\>$keycap\<\/keycap\>";
|
|
|
|
}
|
|
|
|
$mykeys .= '</keycombo>'
|
2002-02-02 04:55:52 +00:00
|
|
|
} else {
|
2002-02-05 04:52:38 +00:00
|
|
|
$mykeys .= "\<keycap\>$keycaps[0]\<\/keycap\>";
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
2002-02-05 04:52:38 +00:00
|
|
|
$replacement = $mykeys;
|
|
|
|
} else {
|
2002-02-16 14:33:24 +00:00
|
|
|
&raiseerror("Unrecognized special substitution code: $specsubstitutions{$tag}");
|
2002-02-05 04:52:38 +00:00
|
|
|
$replacement = $specsubstitutions{$tag};
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
######################
|
|
|
|
# TEXINFO STRUCTURES #
|
|
|
|
######################
|
|
|
|
|
|
|
|
sub crossref {
|
|
|
|
my $anchor;
|
|
|
|
my $link;
|
|
|
|
my $linkname;
|
|
|
|
my $linktitle;
|
|
|
|
my $infofile;
|
|
|
|
my $manualtitle;
|
|
|
|
my $title;
|
|
|
|
my $crossref = '';
|
|
|
|
|
|
|
|
($link, $linkname, $linktitle, $infofile, $manualtitle) = split(/,/, $contents);
|
|
|
|
$link = &trim($link);
|
|
|
|
$linktitle = &trim($linktitle);
|
|
|
|
$linkname = &trim($linkname);
|
|
|
|
$infofile = &trim($infofile);
|
|
|
|
$manualtitle = &trim($manualtitle);
|
|
|
|
|
|
|
|
# build the title that will display in the output
|
|
|
|
#
|
|
|
|
$title = $linktitle;
|
|
|
|
$title .= ': ' if ($title and ($linkname or $infofile));
|
|
|
|
$title .= "($infofile)" if ($infofile);
|
|
|
|
$title .= ' ' if (($title) and ($linkname));
|
|
|
|
$title .= $linkname if ($linkname);
|
|
|
|
|
|
|
|
# Try to pull in the node title if we've already seen it but it
|
|
|
|
# isn't specified in the cross reference.
|
|
|
|
#
|
|
|
|
# If not, we can only display the node name, which is not very good
|
|
|
|
# but the best we can do without writing a two-pass engine.
|
|
|
|
#
|
|
|
|
if (($link) and !($title)) {
|
|
|
|
$title = $nodetitlelookup{$link};
|
|
|
|
$title = $link unless ($title);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ($infofile) {
|
|
|
|
&message("link to another info file, replacing with text") if ($verbose > 1);
|
|
|
|
$crossref = $title;
|
|
|
|
} else {
|
|
|
|
$anchor = &anchorfix($link);
|
|
|
|
$crossref = "<link linkend='$anchor'>$title</link>";
|
|
|
|
&message("made xref to tag $anchor") if ($verbose > 1);
|
|
|
|
}
|
|
|
|
return $crossref;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub inforef {
|
|
|
|
my $anchor;
|
|
|
|
my $link;
|
|
|
|
my $linkname;
|
|
|
|
my $infofile;
|
|
|
|
my $title;
|
|
|
|
my $inforef = '';
|
|
|
|
|
|
|
|
($link, $linkname, $infofile) = split(/,/, $contents);
|
|
|
|
$link = &trim($link);
|
|
|
|
$linkname = &trim($linkname);
|
|
|
|
$infofile = &trim($infofile);
|
|
|
|
|
|
|
|
$title .= "($infofile)" if ($infofile);
|
|
|
|
$title .= $linkname if ($linkname);
|
|
|
|
$title = $link unless ($title);
|
|
|
|
|
|
|
|
if ($infofile) {
|
|
|
|
&message("link to another info file, replacing with text") if ($verbose > 1);
|
|
|
|
$crossref = $title;
|
|
|
|
} else {
|
|
|
|
$anchor = &anchorfix($link);
|
|
|
|
$crossref = "<link linkend='$anchor'>$title</link>";
|
|
|
|
&message("made xref to tag $anchor") if ($verbose > 1);
|
|
|
|
}
|
|
|
|
return $crossref;
|
|
|
|
}
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
sub anchorfix {
|
|
|
|
my $anchor = $_[0];
|
|
|
|
$anchor = lc(&trim($anchor));
|
|
|
|
$anchor = decode_entities($anchor);
|
2002-02-15 14:30:00 +00:00
|
|
|
$anchor =~ s/-/-dash-/g;
|
2002-02-02 04:55:52 +00:00
|
|
|
$anchor =~ s/&/-and-/g;
|
|
|
|
$anchor =~ s/;//g;
|
|
|
|
$anchor = encode_entities($anchor);
|
|
|
|
$anchor =~ s/&(\w)grave/\1/g;
|
|
|
|
$anchor =~ s/&(\w)acute/\1/g;
|
|
|
|
$anchor =~ s/&(\w)circ/\1/g;
|
|
|
|
$anchor =~ s/&(\w)uml/\1/g;
|
|
|
|
$anchor =~ s/&(\w)tilde/\1/g;
|
|
|
|
$anchor =~ s/&(\w)cedil/\1/g;
|
|
|
|
$anchor =~ s/&/-and-/g;
|
|
|
|
$anchor =~ s/;//g;
|
2002-02-15 14:30:00 +00:00
|
|
|
$anchor =~ s/\//-slash-/g;
|
2002-05-25 15:28:01 +00:00
|
|
|
$anchor =~ s/\\/-bslash-/g;
|
2002-02-02 04:55:52 +00:00
|
|
|
$anchor =~ s/\s+/-/g;
|
|
|
|
$anchor =~ s/'//g;
|
2002-03-17 06:16:59 +00:00
|
|
|
$anchor =~ s/`//g;
|
2002-02-15 14:30:00 +00:00
|
|
|
$anchor =~ s/,/-comma-/g;
|
|
|
|
$anchor =~ s/\./-dot-/g;
|
|
|
|
$anchor =~ s/!/-bang-/g;
|
|
|
|
$anchor =~ s/\?/-question-/g;
|
|
|
|
$anchor =~ s/\+/-plus-/g;
|
|
|
|
$anchor =~ s/\*/-x-/g;
|
|
|
|
$anchor =~ s/\(/-op-/g;
|
|
|
|
$anchor =~ s/\)/-cp-/g;
|
2002-02-07 07:34:47 +00:00
|
|
|
$anchor =~ s/\@/-at-/g;
|
2002-02-15 14:30:00 +00:00
|
|
|
$anchor =~ s/dcm_at/-at-/gi;
|
|
|
|
$anchor =~ s/\^/-hat-/g;
|
|
|
|
$anchor =~ s/=/-eq-/g;
|
2002-02-02 04:55:52 +00:00
|
|
|
$anchor =~ s/\$/S/;
|
2002-02-15 14:30:00 +00:00
|
|
|
$anchor =~ s/~/-tilde-/g;
|
|
|
|
$anchor =~ s/0/-zero-/g;
|
|
|
|
$anchor =~ s/1/-one-/g;
|
|
|
|
$anchor =~ s/2/-two-/g;
|
|
|
|
$anchor =~ s/3/-three-/g;
|
|
|
|
$anchor =~ s/4/-four-/g;
|
|
|
|
$anchor =~ s/5/-five-/g;
|
|
|
|
$anchor =~ s/6/-six-/g;
|
|
|
|
$anchor =~ s/7/-seven-/g;
|
|
|
|
$anchor =~ s/8/-eight-/g;
|
|
|
|
$anchor =~ s/9/-nine-/g;
|
|
|
|
$anchor =~ s/\|/-pipe-/g;
|
|
|
|
$anchor =~ s/\[/-lsqb-/g;
|
|
|
|
$anchor =~ s/\]/-rsqb-/g;
|
2002-02-07 07:34:47 +00:00
|
|
|
$anchor =~ s/^-+//;
|
|
|
|
$anchor =~ s/-+$//;
|
2002-02-15 14:30:00 +00:00
|
|
|
$anchor =~ s/--/-/g; # get rid of double, initial and trailing hyphens
|
|
|
|
return &trim($anchor);
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
sub deffn {
|
|
|
|
my $category;
|
|
|
|
my $name;
|
|
|
|
my $arguments;
|
|
|
|
my $argument;
|
|
|
|
my $indeffn = 0;
|
|
|
|
my $indefun = 0;
|
|
|
|
my $indefspec = 0;
|
|
|
|
my $indefmac = 0;
|
|
|
|
|
|
|
|
if ($line =~ /\@deffn/) {
|
|
|
|
$indeffn = 1;
|
|
|
|
$line =~ s/\@deffn\w*//;
|
|
|
|
&message("deffn found") if ($verbose > 1);
|
|
|
|
} elsif ($line =~ /\@defun/) {
|
|
|
|
$indefun = 1;
|
|
|
|
$line =~ s/\@defun\w*//;
|
|
|
|
&message("defun found") if ($verbose > 1);
|
|
|
|
} elsif ($line =~ /\@defspec/) {
|
|
|
|
$indefspec = 1;
|
|
|
|
$line =~ s/\@defspec\w*//;
|
|
|
|
&message("defspec found") if ($verbose > 1);
|
|
|
|
} elsif ($line =~ /\@defmac/) {
|
|
|
|
$indefmac = 1;
|
|
|
|
$line =~ s/\@defmac\w*//;
|
|
|
|
&message("defmac found") if ($verbose > 1);
|
|
|
|
} else {
|
|
|
|
&raiseerror("Unrecognized function definition");
|
|
|
|
}
|
|
|
|
|
|
|
|
&convertinline;
|
|
|
|
|
|
|
|
# DocBook does not allow nested literal tags
|
|
|
|
#
|
|
|
|
$line =~ s/\<literal\>//g;
|
|
|
|
$line =~ s/\<\/literal\>//g;
|
|
|
|
$line = &trim($line);
|
|
|
|
|
|
|
|
# function category names can have spaces. When they do, the name is enclosed in braces:
|
|
|
|
#
|
|
|
|
# @deffn {Interactive Command} isearch-forward
|
|
|
|
# @defun foo bar
|
|
|
|
# @defspec foovar (@var(var))
|
|
|
|
#
|
|
|
|
if ($line =~ /\{/) {
|
2002-02-21 10:52:32 +00:00
|
|
|
&message("function category name enclosed in braces") if ($verbose > 2);
|
2002-02-18 09:04:56 +00:00
|
|
|
($category, $line) = split(/}/, $line);
|
|
|
|
$category =~ s/\{//;
|
|
|
|
($name, $arguments) = split(/ /, $line, 2);
|
|
|
|
} else {
|
|
|
|
if ($indeffn) {
|
|
|
|
&message("function category name not enclosed in braces") if ($verbose > 2);
|
|
|
|
($category, $name, $arguments) = split(/\s/, $line, 3);
|
|
|
|
} elsif ($indefun) {
|
|
|
|
$category = 'Function';
|
|
|
|
($name, $arguments) = split(/ /, $line, 2);
|
|
|
|
} elsif ($indefspec) {
|
|
|
|
$category = 'Special Form';
|
|
|
|
($name, $arguments) = split(/ /, $line, 2);
|
|
|
|
} elsif ($indefmac) {
|
|
|
|
$category = 'Macro';
|
|
|
|
($name, $arguments) = split(/ /, $line, 2);
|
|
|
|
} else {
|
|
|
|
&raiseerror("Unrecognized function type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
&message("category: $category, name: $name, arguments: $arguments") if ($verbose > 1);
|
|
|
|
$line = $category . ': <funcsynopsis><funcprototype>';
|
|
|
|
&writeconverted;
|
|
|
|
$line = '<funcdef><function>' . $name . '</function>';
|
|
|
|
&writeline;
|
|
|
|
$line = '</funcdef>';
|
|
|
|
&writeline;
|
|
|
|
foreach $argument (split(' ', $arguments)) {
|
|
|
|
$line = '<paramdef><parameter>' . $argument . '</parameter></paramdef>';
|
|
|
|
&writeline;
|
|
|
|
}
|
|
|
|
$line = '</funcprototype></funcsynopsis>';
|
|
|
|
&writeline;
|
|
|
|
}
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
#############
|
|
|
|
# META-DATA #
|
|
|
|
#############
|
|
|
|
|
|
|
|
# this routine processes meta-data @-Commands
|
|
|
|
#
|
|
|
|
sub meta {
|
|
|
|
return if (&metaarg('\@setfilename', $sgmlfile));
|
|
|
|
return if (&metaarg('\@settitle', $title));
|
2002-05-25 15:32:11 +00:00
|
|
|
return if (&metaarg('\@documentlanguage',$lang));
|
2002-02-02 04:55:52 +00:00
|
|
|
return if (&metaarg('\@author', $authorname));
|
|
|
|
&raiseerror("Unknown meta-data command $line");
|
|
|
|
}
|
|
|
|
|
|
|
|
# Meta-data commands have arguments,
|
|
|
|
# so if the pattern matches, store the argument
|
|
|
|
# to the variable in $_[1]
|
|
|
|
#
|
|
|
|
sub metaarg {
|
|
|
|
my $pattern = $_[0];
|
|
|
|
if ($line =~ /$pattern/) {
|
2002-02-18 09:04:56 +00:00
|
|
|
$line =~ s/$pattern//;
|
|
|
|
&convertinline;
|
2002-02-21 10:52:32 +00:00
|
|
|
&normalizespecial($line);
|
2002-02-02 04:55:52 +00:00
|
|
|
$_[1] = $line;
|
2002-02-18 09:04:56 +00:00
|
|
|
&message("set $pattern to $line") if ($verbose > 2);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
################
|
|
|
|
# WRITE OUTPUT #
|
|
|
|
################
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
sub writeconverted {
|
2002-02-02 04:55:52 +00:00
|
|
|
my $temp = &trim($line);
|
|
|
|
|
2002-02-21 10:52:32 +00:00
|
|
|
unless ($suppresspara) {
|
|
|
|
if ($temp eq '') {
|
|
|
|
&closeformalpara;
|
|
|
|
} else {
|
|
|
|
unless (($inpara) or ($nest[-1] eq 'table') or ($nest[-1] eq 'multi')) {
|
|
|
|
if (($nodename) and ($nodeinit == 0) and !($inabstract)) {
|
|
|
|
&guessnodelevel;
|
|
|
|
}
|
|
|
|
¶
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-02-21 10:52:32 +00:00
|
|
|
|
|
|
|
unless ($suppressconversion) {
|
|
|
|
&convertinline;
|
|
|
|
}
|
2002-02-18 09:04:56 +00:00
|
|
|
&writeline;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub writeline {
|
2002-02-21 10:52:32 +00:00
|
|
|
&normalizespecial($line);
|
2002-02-16 14:33:24 +00:00
|
|
|
&message("OUT: $line") if ($verbose > 1);
|
2002-02-02 04:55:52 +00:00
|
|
|
$buf .= $line . "\n";
|
2002-02-07 07:34:47 +00:00
|
|
|
if (($linenumber % 1000 == 0) and ($inabstract == 0)) {
|
2002-02-05 04:52:38 +00:00
|
|
|
print $outfh $buf;
|
|
|
|
$buf = '';
|
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
#########
|
|
|
|
# NODES #
|
|
|
|
#########
|
2002-02-02 04:55:52 +00:00
|
|
|
|
|
|
|
# this is for when the source never set a position for this node in the
|
|
|
|
# chapter-style hierarchy, which we use.
|
|
|
|
#
|
|
|
|
# We have to make a best guess based on the node's settings,
|
|
|
|
# so put it right under whoever it calls the "up" node.
|
|
|
|
#
|
2002-02-18 09:04:56 +00:00
|
|
|
sub guessnodelevel {
|
|
|
|
return if ($nodeinit);
|
2002-02-19 05:02:23 +00:00
|
|
|
&message("guessing level for node: $nodename, title: $nodetitle") if ($verbose > 2);
|
2002-02-18 09:04:56 +00:00
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
my $parentname = $nodeup;
|
|
|
|
my $parentlevel = $nodelevels{$parentname};
|
2002-02-18 09:04:56 +00:00
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
if ($parentlevel == "A") {
|
2002-02-19 05:02:23 +00:00
|
|
|
§1($nodetitle);
|
2002-02-02 04:55:52 +00:00
|
|
|
} elsif ($parentlevel == 1) {
|
2002-02-19 05:02:23 +00:00
|
|
|
§2($nodetitle);
|
2002-02-02 04:55:52 +00:00
|
|
|
} elsif ($parentlevel == 2) {
|
2002-02-19 05:02:23 +00:00
|
|
|
§3($nodetitle);
|
2002-02-02 04:55:52 +00:00
|
|
|
} elsif ($parentlevel == 3) {
|
2002-02-19 05:02:23 +00:00
|
|
|
§4($nodetitle);
|
2002-02-02 04:55:52 +00:00
|
|
|
} else {
|
|
|
|
&raiseerror("The parent node, $parentname, could not be found.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
# Sets up node variables.
|
|
|
|
#
|
|
|
|
# The node isn't actually created until we hit some text in it.
|
|
|
|
#
|
2002-02-02 04:55:52 +00:00
|
|
|
sub node {
|
2002-02-07 07:34:47 +00:00
|
|
|
$line =~ s/\@node\s+?//;
|
2002-02-02 04:55:52 +00:00
|
|
|
&convertinline;
|
2002-02-21 10:52:32 +00:00
|
|
|
&normalizespecial($line);
|
2002-02-02 04:55:52 +00:00
|
|
|
($nodename, $nodenext, $nodeprev, $nodeup) = split(/,/, $line);
|
|
|
|
$nodename = &trim($nodename);
|
2002-02-18 09:04:56 +00:00
|
|
|
$nodetitle = $nodename;
|
2002-02-02 04:55:52 +00:00
|
|
|
$nodeprev = &trim($nodeprev);
|
|
|
|
$nodenext = &trim($nodenext);
|
|
|
|
$nodeup = &trim($nodeup);
|
2002-02-18 09:04:56 +00:00
|
|
|
$nodeid = &anchorfix($nodename);
|
2002-02-02 04:55:52 +00:00
|
|
|
$nodeinit = 0;
|
2002-02-15 14:30:00 +00:00
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
&message("Node: $nodename") if ($verbose);
|
2002-02-19 05:02:23 +00:00
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
&closeformalpara;
|
2002-02-15 14:30:00 +00:00
|
|
|
}
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
# Creates the node
|
2002-02-15 14:30:00 +00:00
|
|
|
#
|
2002-02-18 09:04:56 +00:00
|
|
|
sub initnode {
|
|
|
|
$nodeid = 0 if (exists $nodeanchors{uc($nodename)});
|
|
|
|
if ($nodeinit) {
|
2002-02-15 14:30:00 +00:00
|
|
|
$nodeid = 0;
|
2002-02-18 09:04:56 +00:00
|
|
|
return;
|
2002-02-15 14:30:00 +00:00
|
|
|
}
|
2002-02-18 09:04:56 +00:00
|
|
|
&message("initiating node $nodename") if ($verbose > 2);
|
|
|
|
$nodenames{$nodename} = $nodename;
|
|
|
|
$nodenexts{$nodename} = $nodenext;
|
|
|
|
$nodeprevs{$nodename} = $nodeprev;
|
|
|
|
$nodeups{$nodename} = $nodeup;
|
2002-03-17 06:16:59 +00:00
|
|
|
$nodeanchors{uc($nodename)} = $nodeid if ($nodeid);
|
2002-02-19 05:02:23 +00:00
|
|
|
$nodetitlelookup{$nodeid} = $nodetitle;
|
2002-02-18 09:04:56 +00:00
|
|
|
$nodeinit = 1;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
2002-02-21 10:52:32 +00:00
|
|
|
sub menu {
|
|
|
|
$inmenu = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub menuitem {
|
|
|
|
$line =~ s/^\*\s*//;
|
|
|
|
&message("menu line: $line");
|
|
|
|
}
|
|
|
|
|
|
|
|
sub closemenu {
|
|
|
|
$inmenu = 0;
|
|
|
|
}
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
####################
|
|
|
|
# DOCBOOK SECTIONS #
|
|
|
|
####################
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
sub appendix {
|
2002-02-19 05:02:23 +00:00
|
|
|
&writeabstract;
|
|
|
|
&message("appendix: $nodetitle") if ($verbose > 1);
|
2002-02-02 04:55:52 +00:00
|
|
|
&closeappendix;
|
2002-03-17 06:16:59 +00:00
|
|
|
if ($nodeinit) {
|
|
|
|
§($_[0]);
|
|
|
|
} else {
|
|
|
|
$nodetitle = $_[0];
|
|
|
|
}
|
2002-02-18 09:04:56 +00:00
|
|
|
&initnode;
|
2002-02-19 05:02:23 +00:00
|
|
|
&convertinline;
|
2002-03-10 16:32:16 +00:00
|
|
|
&normalizespecial($nodetitle);
|
2002-02-15 14:30:00 +00:00
|
|
|
if ($nodeid) {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<appendix id='$nodeid'\>\<title id='$nodeid-title'\>$nodetitle<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
} else {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<appendix\>\<title\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
$inappendix = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub sect1 {
|
2002-02-19 05:02:23 +00:00
|
|
|
&writeabstract;
|
|
|
|
&message("sect1: $nodetitle") if ($verbose > 1);
|
2002-05-25 22:44:15 +00:00
|
|
|
&closeappendix;
|
2002-03-17 06:16:59 +00:00
|
|
|
if ($nodeinit) {
|
|
|
|
§($_[0]);
|
|
|
|
} else {
|
|
|
|
$nodetitle = $_[0];
|
|
|
|
}
|
2002-02-18 09:04:56 +00:00
|
|
|
&initnode;
|
|
|
|
&convertinline;
|
2002-02-21 10:52:32 +00:00
|
|
|
&normalizespecial($nodetitle);
|
2002-02-15 14:30:00 +00:00
|
|
|
if ($nodeid) {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect1 id='$nodeid'\>\<title id='$nodeid-title'\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
} else {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect1\>\<title\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
$insect1 = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub sect2 {
|
2002-02-19 05:02:23 +00:00
|
|
|
&writeabstract;
|
|
|
|
&message("sect1: $nodetitle") if ($verbose > 1);
|
2002-02-02 04:55:52 +00:00
|
|
|
&closesect2;
|
2002-03-17 06:16:59 +00:00
|
|
|
if ($nodeinit) {
|
|
|
|
§($_[0]);
|
|
|
|
} else {
|
|
|
|
$nodetitle = $_[0];
|
|
|
|
}
|
2002-02-18 09:04:56 +00:00
|
|
|
&initnode;
|
|
|
|
&convertinline;
|
2002-02-21 10:52:32 +00:00
|
|
|
&normalizespecial($nodetitle);
|
2002-02-02 04:55:52 +00:00
|
|
|
if ($inappendix) {
|
2002-02-15 14:30:00 +00:00
|
|
|
if ($nodeid) {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect1 id='$nodeid'\>\<title id='$nodeid-title'\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
} else {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect1\>\<title\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
$nodelevels{$nodename} = 1;
|
|
|
|
} else {
|
2002-02-15 14:30:00 +00:00
|
|
|
if ($nodeid) {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect2 id='$nodeid'\>\<title id='$nodeid-title'\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
} else {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect2\>\<title\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
$nodelevels{$nodename} = 2;
|
|
|
|
}
|
|
|
|
$insect2 = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub sect3 {
|
2002-02-19 05:02:23 +00:00
|
|
|
&writeabstract;
|
|
|
|
&message("sect1: $nodetitle") if ($verbose > 1);
|
2002-02-02 04:55:52 +00:00
|
|
|
&closesect3;
|
2002-03-17 06:16:59 +00:00
|
|
|
if ($nodeinit) {
|
|
|
|
§($_[0]);
|
|
|
|
} else {
|
|
|
|
$nodetitle = $_[0];
|
|
|
|
}
|
2002-02-18 09:04:56 +00:00
|
|
|
&initnode;
|
|
|
|
&convertinline;
|
2002-02-21 10:52:32 +00:00
|
|
|
&normalizespecial($nodetitle);
|
2002-02-02 04:55:52 +00:00
|
|
|
if ($inappendix) {
|
2002-02-15 14:30:00 +00:00
|
|
|
if ($nodeid) {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect2 id='$nodeid'\>\<title id='$nodeid-title'\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
} else {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect2\>\<title\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
$nodelevels{$nodename} = 2;
|
|
|
|
} else {
|
2002-02-15 14:30:00 +00:00
|
|
|
if ($nodeid) {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect3 id='$nodeid'\>\<title id='$nodeid-title'\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
} else {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect3\>\<title\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
$nodelevels{$nodename} = 3;
|
|
|
|
}
|
|
|
|
$insect3 = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub sect4 {
|
2002-02-19 05:02:23 +00:00
|
|
|
&writeabstract;
|
2002-03-17 06:16:59 +00:00
|
|
|
&message("sect4: $nodetitle") if ($verbose > 1);
|
2002-02-02 04:55:52 +00:00
|
|
|
&closesect4;
|
2002-03-17 06:16:59 +00:00
|
|
|
if ($nodeinit) {
|
|
|
|
§($_[0]);
|
|
|
|
} else {
|
|
|
|
$nodetitle = $_[0];
|
|
|
|
}
|
2002-02-18 09:04:56 +00:00
|
|
|
&initnode;
|
|
|
|
&convertinline;
|
2002-02-21 10:52:32 +00:00
|
|
|
&normalizespecial($nodetitle);
|
2002-02-02 04:55:52 +00:00
|
|
|
if ($inappendix) {
|
2002-02-15 14:30:00 +00:00
|
|
|
if ($nodeid) {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect3 id='$nodeid'\>\<title id='$nodeid-title'\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
} else {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect3\>\<title\>$nodetitlee\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
$nodelevels{$nodename} = 3;
|
|
|
|
} else {
|
2002-02-15 14:30:00 +00:00
|
|
|
if ($nodeid) {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect4 id='$nodeid'\>\<title id='$nodeid-title'\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
} else {
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "\<sect4\>\<title\>$nodetitle\<\/title\>\n";
|
2002-02-15 14:30:00 +00:00
|
|
|
}
|
2002-02-18 09:04:56 +00:00
|
|
|
$nodelevels{$nodename} = 4444;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
$insect4 = 1;
|
|
|
|
}
|
|
|
|
|
2002-03-17 06:16:59 +00:00
|
|
|
sub sect {
|
|
|
|
$nodetitle = $_[0];
|
|
|
|
&normalizespecial($nodetitle);
|
|
|
|
$nodename = $nodetitle;
|
|
|
|
$nodename = &trim($nodename);
|
|
|
|
$nodeprev = '';
|
|
|
|
$nodenext = '';
|
|
|
|
$nodeup = '';
|
|
|
|
$nodeid = &anchorfix($nodename);
|
|
|
|
$nodeid = 0 if (exists $nodeanchors{uc($nodename)});
|
|
|
|
$nodeanchors{uc($nodename)} = $nodeid if ($nodeid);
|
|
|
|
$nodeinit = 0;
|
|
|
|
|
|
|
|
&message("Section Node: $nodename") if ($verbose);
|
|
|
|
|
|
|
|
&closeformalpara;
|
|
|
|
}
|
|
|
|
|
2002-02-16 14:33:24 +00:00
|
|
|
sub multitable {
|
2002-02-18 09:04:56 +00:00
|
|
|
my @colwidths = ();
|
|
|
|
my $colcount = 0;
|
2002-02-16 14:33:24 +00:00
|
|
|
my $colspecs = '';
|
|
|
|
|
|
|
|
&closepara;
|
|
|
|
$line =~ s/\@\w+\s+//;
|
|
|
|
|
|
|
|
# fractional column widths are supported
|
|
|
|
# but prototypes are ignored, as DocBook will do the same
|
|
|
|
# thing automatically without them.
|
|
|
|
#
|
|
|
|
if ($line =~ /\@columnfractions/) {
|
2002-02-18 09:04:56 +00:00
|
|
|
&message("starting multicolumn table") if ($verbose > 1);
|
2002-02-16 14:33:24 +00:00
|
|
|
$line =~ s/\@columnfractions\s+//;
|
2002-02-18 09:04:56 +00:00
|
|
|
@colwidths = split(/\s+/, $line);
|
|
|
|
$colcount = scalar @colwidths;
|
|
|
|
foreach $colwidth (@colwidths) {
|
|
|
|
$colwidth =~ s/\.//;
|
|
|
|
$colwidth .= '0' if (length($colwidth) < 2);
|
|
|
|
$colspecs .= "\<colspec colwidth='$colwidth\*'\/\>\n";
|
2002-02-16 14:33:24 +00:00
|
|
|
}
|
2002-02-18 09:04:56 +00:00
|
|
|
} else {
|
|
|
|
$colcount = scalar split(/\{/, $line) - 1;
|
|
|
|
}
|
|
|
|
if (($nest[-1] eq 'table') or ($nest[-1] eq 'multi')) {
|
|
|
|
&closetablecol;
|
|
|
|
$buf .= '<entrytbl cols=' . "'" . $colcount . "'" . "\>\n";
|
|
|
|
} else {
|
|
|
|
$buf .= '<informaltable><tgroup cols=' . "'" . $colcount . "'" . "\>\n";
|
2002-02-16 14:33:24 +00:00
|
|
|
}
|
2002-02-18 09:04:56 +00:00
|
|
|
$buf .= "$colspecs\n" if ($colspecs);
|
2002-02-16 14:33:24 +00:00
|
|
|
$buf .= '<tbody>' . "\n";
|
2002-02-18 09:04:56 +00:00
|
|
|
push @nest, 'multi';
|
|
|
|
push @incol, 0;
|
|
|
|
push @inrow, 0;
|
|
|
|
push @infirstcol, 0;
|
|
|
|
push @initem, 0;
|
|
|
|
push @tableformat, '';
|
2002-02-16 14:33:24 +00:00
|
|
|
}
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
sub table {
|
2002-02-16 14:33:24 +00:00
|
|
|
&closepara;
|
2002-02-18 09:04:56 +00:00
|
|
|
|
|
|
|
if (($nest[-1] eq 'table') or ($nest[-1] eq 'multi')) {
|
|
|
|
&closetablecol;
|
|
|
|
$buf .= '<entrytbl cols=' . "'2'" . '><tbody>' . "\n";
|
|
|
|
} else {
|
|
|
|
$buf .= '<informaltable><tgroup cols=' . "'2'" . '><tbody>' . "\n";
|
|
|
|
}
|
|
|
|
push @nest, 'table';
|
|
|
|
push @incol, 0;
|
|
|
|
push @inrow, 0;
|
|
|
|
push @infirstcol, 0;
|
|
|
|
push @initem, 0;
|
|
|
|
push @tableformat, '';
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub tablerow {
|
|
|
|
&closetablerow;
|
|
|
|
$buf .= '<row>';
|
2002-02-18 09:04:56 +00:00
|
|
|
$inrow[-1] = 1;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub tablecol {
|
|
|
|
&closetablecol;
|
|
|
|
$buf .= '<entry>';
|
2002-02-18 09:04:56 +00:00
|
|
|
$incol[-1] = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub tableline {
|
|
|
|
&message("table: $line") if ($verbose > 2);
|
|
|
|
if ($nest[-1] ne 'multi') {
|
|
|
|
if ($infirstcol[-1]) {
|
2002-02-21 10:52:32 +00:00
|
|
|
# $buf .= '</literallayout>';
|
2002-02-18 09:04:56 +00:00
|
|
|
&closetablecol;
|
|
|
|
&tablecol;
|
|
|
|
$infirstcol[-1] = 0;
|
|
|
|
}
|
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub orderedlist {
|
|
|
|
&closeformalpara;
|
|
|
|
$buf .= '<orderedlist>';
|
2002-02-18 09:04:56 +00:00
|
|
|
push @nest, 'ordered';
|
|
|
|
push @initem, 0;
|
2002-03-10 15:06:43 +00:00
|
|
|
# $suppresspara++;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub itemizedlist {
|
|
|
|
&closeformalpara;
|
|
|
|
$buf .= '<itemizedlist>';
|
2002-02-18 09:04:56 +00:00
|
|
|
push @nest, 'itemized';
|
|
|
|
push @initem, 0;
|
2002-03-10 15:06:43 +00:00
|
|
|
# $suppresspara++;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub item {
|
2002-02-18 09:04:56 +00:00
|
|
|
$line =~ s/\@item\w*\s*//;
|
|
|
|
if ($nest[-1] eq 'table') {
|
2002-02-15 14:30:00 +00:00
|
|
|
&message("table item: $line") if ($verbose > 2);
|
2002-02-21 10:52:32 +00:00
|
|
|
if ($infirstcol[-1]) {
|
|
|
|
$buf .= ', ';
|
|
|
|
}
|
2002-02-18 09:04:56 +00:00
|
|
|
unless ($infirstcol[-1]) {
|
2002-02-15 14:30:00 +00:00
|
|
|
&tablerow;
|
|
|
|
&tablecol;
|
2002-02-18 09:04:56 +00:00
|
|
|
$infirstcol[-1] = 1;
|
2002-02-21 10:52:32 +00:00
|
|
|
# $buf .= '<literallayout>';
|
2002-02-15 14:30:00 +00:00
|
|
|
}
|
|
|
|
$line = &trim($line);
|
2002-02-18 09:04:56 +00:00
|
|
|
$line = $tableformat[-1] . "\{$line\}" unless ($tableformat[-1] eq '@asis');
|
|
|
|
} elsif ($nest[-1] eq 'multi') {
|
|
|
|
&message("multitable item: $line") if ($verbose > 2);
|
|
|
|
&tablerow;
|
|
|
|
&tablecol;
|
2002-02-21 10:52:32 +00:00
|
|
|
# $line =~ s/^(.)/\<literallayout\>$1/;
|
|
|
|
# $line =~ s/\@tab/\<\/literallayout\>\@tab/;
|
2002-02-18 09:04:56 +00:00
|
|
|
$line =~ s/\s*\@tab\s*/\<\/entry\>\<entry\>/g;
|
|
|
|
} elsif (($nest[-1] eq 'ordered') or ($nest[-1] eq 'itemized')) {
|
2002-02-02 04:55:52 +00:00
|
|
|
&listitem;
|
2002-02-18 09:04:56 +00:00
|
|
|
} else {
|
|
|
|
&raiseerror("item tag found, but we're not in a list. Nest depth: " . scalar @nest);
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub listitem {
|
|
|
|
&closelistitem;
|
|
|
|
$buf .= '<listitem>';
|
2002-03-10 16:32:16 +00:00
|
|
|
# ¶
|
2002-02-18 09:04:56 +00:00
|
|
|
$initem[-1] = 1;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub formalpara {
|
|
|
|
my $title = $_[0];
|
|
|
|
my $id = &anchorfix($title);
|
|
|
|
|
|
|
|
&closeformalpara;
|
|
|
|
#$buf .= "\<formalpara id='$id'\>\<title\>$title\<\/title\>\n\<para\>";
|
|
|
|
$informalpara = 1;
|
|
|
|
$inpara = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub para {
|
|
|
|
&closeformalpara;
|
|
|
|
$buf .= '<para>';
|
|
|
|
$inpara = 1;
|
|
|
|
}
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
sub literalblock {
|
2002-02-02 04:55:52 +00:00
|
|
|
if ($pattern =~ /\bformat\b/) {
|
2002-02-18 09:04:56 +00:00
|
|
|
&message("start programlisting") if ($verbose > 2);
|
2002-02-21 10:52:32 +00:00
|
|
|
$suppresspara++;
|
2002-03-10 15:06:43 +00:00
|
|
|
$literaltag = 'programlisting';
|
2002-02-18 09:04:56 +00:00
|
|
|
} elsif ($pattern =~ /\bexample\b/) {
|
|
|
|
&message("start programlisting") if ($verbose > 2);
|
2002-02-21 10:52:32 +00:00
|
|
|
$suppresspara++;
|
2002-03-10 15:06:43 +00:00
|
|
|
$literaltag = 'programlisting';
|
2002-02-21 10:52:32 +00:00
|
|
|
} elsif ($pattern =~ /\bsmallexample\b/) {
|
2002-02-18 09:04:56 +00:00
|
|
|
&message("start programlisting") if ($verbose > 2);
|
2002-02-21 10:52:32 +00:00
|
|
|
$suppresspara++;
|
2002-03-10 15:06:43 +00:00
|
|
|
$literaltag = 'programlisting';
|
2002-02-21 10:52:32 +00:00
|
|
|
} elsif ($pattern =~ /\bdisplay\b/) {
|
|
|
|
&message("start literallayout") if ($verbose > 2);
|
|
|
|
$suppresspara++;
|
2002-03-10 15:06:43 +00:00
|
|
|
$literaltag = 'literallayout';
|
2002-02-21 10:52:32 +00:00
|
|
|
} elsif ($pattern =~ /\blisp\b/) {
|
2002-02-18 09:04:56 +00:00
|
|
|
&message("start programlisting") if ($verbose > 2);
|
2002-02-21 10:52:32 +00:00
|
|
|
$suppressconversion++;
|
|
|
|
$suppresspara++;
|
2002-03-10 15:06:43 +00:00
|
|
|
$literaltag = 'programlisting';
|
|
|
|
} elsif ($pattern =~ /\bquotation\b/) {
|
|
|
|
&message("start quotation") if ($verbose > 2);
|
|
|
|
$literaltag = 'blockquote';
|
2002-02-18 09:04:56 +00:00
|
|
|
} elsif ($pattern =~ /\bverbatim\b/) {
|
|
|
|
&message("start programlisting") if ($verbose > 2);
|
2002-02-21 10:52:32 +00:00
|
|
|
$suppressconversion++;
|
|
|
|
$suppresspara++;
|
2002-03-10 15:06:43 +00:00
|
|
|
$literaltag = 'programlisting';
|
2002-02-16 14:33:24 +00:00
|
|
|
} else {
|
|
|
|
&raiseerror("Unrecognized literal: $pattern");
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
2002-03-10 15:06:43 +00:00
|
|
|
if (scalar @literal) {
|
|
|
|
&message("Not including tag $literaltag, due to nested literal blocks") if ($verbose > 2);
|
|
|
|
$literaltag = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
$buf .= '<' . $literaltag . '>' . "\n" if ($literaltag);
|
2002-02-21 10:52:32 +00:00
|
|
|
$literalendtag = $pattern;
|
|
|
|
$literalendtag =~ s/\@/\@end /;
|
|
|
|
push @literal, $literaltag;
|
|
|
|
push @literalend, $literalendtag;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
sub comment {
|
2002-02-19 05:02:23 +00:00
|
|
|
my $start = '';
|
|
|
|
my $comment = '';
|
|
|
|
|
|
|
|
if ($line =~ /\@c\b/) {
|
|
|
|
($start, $comment) = split(/\@c\b/, $line, 2);
|
|
|
|
} elsif ($line =~ /\@comment\b/) {
|
|
|
|
($start, $comment) = split(/\@comment\b/, $line, 2);
|
|
|
|
} else {
|
|
|
|
&raiseerror("error locating the comment");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
while ($comment =~ /--/) {
|
|
|
|
$comment =~ s/--/-/g;
|
|
|
|
}
|
|
|
|
$line = '<!-- ' . $comment . ' -->';
|
|
|
|
&writeline;
|
|
|
|
$line = $start;
|
2002-02-18 09:04:56 +00:00
|
|
|
}
|
|
|
|
|
2002-05-25 22:44:15 +00:00
|
|
|
sub indexterm {
|
|
|
|
$buf .= "\<indexterm\>\<primary\>$_[0]\</primary\>\</indexterm\>\n";
|
|
|
|
}
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
sub closeappendix {
|
|
|
|
&closesect1;
|
|
|
|
if ($inappendix) {
|
2002-02-18 09:04:56 +00:00
|
|
|
&message("closing appendix") if ($verbose > 2);
|
2002-02-02 04:55:52 +00:00
|
|
|
$buf .= '</appendix>' . "\n";
|
|
|
|
$inappendix = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub closesect1 {
|
|
|
|
&closesect2;
|
|
|
|
if ($insect1) {
|
2002-02-18 09:04:56 +00:00
|
|
|
&message("closing sect1") if ($verbose > 2);
|
2002-02-02 04:55:52 +00:00
|
|
|
$buf .= '</sect1>' . "\n\n";
|
|
|
|
$insect1 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub closesect2 {
|
|
|
|
&closesect3;
|
|
|
|
if ($insect2) {
|
2002-02-18 09:04:56 +00:00
|
|
|
&message("closing sect2") if ($verbose > 2);
|
2002-02-02 04:55:52 +00:00
|
|
|
if ($inappendix) {
|
|
|
|
$buf .= '</sect1>' . "\n\n";
|
|
|
|
} else {
|
|
|
|
$buf .= '</sect2>' . "\n\n";
|
|
|
|
}
|
|
|
|
$insect2 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub closesect3 {
|
|
|
|
&closesect4;
|
|
|
|
if ($insect3) {
|
2002-02-18 09:04:56 +00:00
|
|
|
&message("closing sect3") if ($verbose > 2);
|
2002-02-02 04:55:52 +00:00
|
|
|
if ($inappendix) {
|
|
|
|
$buf .= '</sect2>' . "\n\n";
|
|
|
|
} else {
|
|
|
|
$buf .= '</sect3>' . "\n\n";
|
|
|
|
}
|
|
|
|
$insect3 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub closesect4 {
|
|
|
|
&closeformalpara;
|
2002-02-18 09:04:56 +00:00
|
|
|
&closenest;
|
2002-02-02 04:55:52 +00:00
|
|
|
if ($insect4) {
|
2002-02-18 09:04:56 +00:00
|
|
|
&message("closing sect4") if ($verbose > 2);
|
2002-02-02 04:55:52 +00:00
|
|
|
if ($inappendix) {
|
|
|
|
$buf .= '</sect3>' . "\n\n";
|
|
|
|
} else {
|
|
|
|
$buf .= '</sect4>' . "\n\n";
|
|
|
|
}
|
|
|
|
$insect4 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
sub closenest {
|
|
|
|
my $runaway = 0;
|
|
|
|
while (scalar @nest) {
|
|
|
|
&closetable;
|
|
|
|
&closeorderedlist;
|
|
|
|
&closeitemizedlist;
|
|
|
|
$runaway++;
|
|
|
|
&raiseerror("Runaway nesting") if ($runaway >= 100);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
sub closetable {
|
|
|
|
&closetablerow;
|
2002-02-18 09:04:56 +00:00
|
|
|
if (($nest[-1] eq 'table') or ($nest[-1] eq 'multi')) {
|
|
|
|
&message("closing table") if ($verbose > 2);
|
|
|
|
if (($nest[-2] eq 'table') or ($nest[-2] eq 'multi')) {
|
|
|
|
$buf .= '</tbody></entrytbl>' . "\n";
|
|
|
|
} else {
|
|
|
|
$buf .= '</tbody></tgroup></informaltable>' . "\n";
|
|
|
|
}
|
|
|
|
pop @nest;
|
|
|
|
pop @incol;
|
|
|
|
pop @inrow;
|
|
|
|
pop @infirstcol;
|
|
|
|
pop @initem;
|
|
|
|
pop @tableformat;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub closetablerow {
|
|
|
|
&closetablecol;
|
2002-02-18 09:04:56 +00:00
|
|
|
if ($inrow[-1]) {
|
|
|
|
&message("closing table row") if ($verbose > 2);
|
2002-02-02 04:55:52 +00:00
|
|
|
$buf .= '</row>' . "\n";
|
2002-02-18 09:04:56 +00:00
|
|
|
$inrow[-1] = 0;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub closetablecol {
|
2002-02-18 09:04:56 +00:00
|
|
|
if ($incol[-1]) {
|
|
|
|
&message("closing table column") if ($verbose > 2);
|
2002-02-02 04:55:52 +00:00
|
|
|
$buf .= '</entry>' . "\n";
|
2002-02-18 09:04:56 +00:00
|
|
|
$incol[-1] = 0;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub closeorderedlist {
|
|
|
|
&closelistitem;
|
2002-02-18 09:04:56 +00:00
|
|
|
if ($nest[-1] eq 'ordered') {
|
|
|
|
&message("closing ordered list") if ($verbose > 2);
|
2002-02-02 04:55:52 +00:00
|
|
|
$buf .= '</orderedlist>' . "\n";
|
2002-02-18 09:04:56 +00:00
|
|
|
pop @nest;
|
|
|
|
pop @initem;
|
2002-03-10 15:06:43 +00:00
|
|
|
# $suppresspara--;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub closeitemizedlist {
|
|
|
|
&closelistitem;
|
2002-02-18 09:04:56 +00:00
|
|
|
if ($nest[-1] eq 'itemized') {
|
|
|
|
&message("closing itemized list") if ($verbose > 2);
|
2002-02-02 04:55:52 +00:00
|
|
|
$buf .= '</itemizedlist>' . "\n";
|
2002-02-18 09:04:56 +00:00
|
|
|
pop @nest;
|
|
|
|
pop @initem;
|
2002-03-10 15:06:43 +00:00
|
|
|
# $suppresspara--;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub closelistitem {
|
|
|
|
&closeformalpara;
|
2002-02-18 09:04:56 +00:00
|
|
|
if ((($nest[-1] eq 'ordered') or (@nest[-1] eq 'itemized')) and (@initem[-1])) {
|
|
|
|
&message("closing list item") if ($verbose > 2);
|
2002-03-10 15:06:43 +00:00
|
|
|
#$buf .= '</para></listitem>' . "\n";
|
2002-02-02 04:55:52 +00:00
|
|
|
$buf .= '</listitem>' . "\n";
|
2002-02-18 09:04:56 +00:00
|
|
|
$initem[-1] = 0;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub closeformalpara {
|
|
|
|
&closepara;
|
|
|
|
if ($informalpara) {
|
|
|
|
# $buf .= '</formalpara>';
|
|
|
|
$informalpara = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub closepara {
|
|
|
|
if ($inpara) {
|
|
|
|
$buf .= '</para>';
|
|
|
|
$inpara = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-02-21 10:52:32 +00:00
|
|
|
sub closeliteralblock {
|
|
|
|
if (scalar @literal) {
|
2002-03-10 15:06:43 +00:00
|
|
|
foreach $tag (split(/,/, $literal[-1])) {
|
|
|
|
$buf .= '</' . &trim($tag) . '>' . "\n";
|
|
|
|
}
|
2002-02-02 04:55:52 +00:00
|
|
|
$literal = '';
|
2002-02-21 10:52:32 +00:00
|
|
|
$literalend = '';
|
|
|
|
$suppressconversion--;
|
|
|
|
$suppressconversion = 0 if ($suppressconversion < 0);
|
|
|
|
$suppresspara--;
|
2002-03-10 15:06:43 +00:00
|
|
|
&raiseerror("Literal block nesting error") if ($suppresspara < 0);
|
2002-02-21 10:52:32 +00:00
|
|
|
$suppresspara = 0 if ($suppresspara < 0);
|
|
|
|
pop @literal;
|
|
|
|
pop @literalend;
|
|
|
|
$literaltag = $literal[-1];
|
|
|
|
$literalendtag = $literalend[-1];
|
|
|
|
&message("literalendtag: $literalendtag") if ($verbose > 2);
|
|
|
|
&message("literal depth: " . scalar @literal . ", para: $suppresspara, conv: $suppressconversion") if ($verbose > 2);
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
################
|
|
|
|
# CONDITIONALS #
|
|
|
|
################
|
|
|
|
|
|
|
|
sub set {
|
|
|
|
my ($name,
|
|
|
|
$value);
|
|
|
|
|
2002-02-18 09:04:56 +00:00
|
|
|
($foo, $name, $value) = split(/\s+/, $line, 3);
|
2002-02-02 04:55:52 +00:00
|
|
|
$value = 1 unless ($value);
|
|
|
|
$setvalues{$name} = $value;
|
|
|
|
&message("set $name to $value") if ($verbose > 1);
|
|
|
|
$value = $setvalues{$name};
|
|
|
|
&message("read back $value") if ($verbose > 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub clear {
|
|
|
|
my $name;
|
|
|
|
|
|
|
|
($foo, $name) = split(/\s+/, $line);
|
|
|
|
$setvalues{$name} = 0;
|
|
|
|
&message("cleared $name") if ($verbose > 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ifset {
|
|
|
|
my $name;
|
|
|
|
|
|
|
|
($foo, $name) = split(/\s+/, $line);
|
|
|
|
return $ifsets{$name};
|
|
|
|
}
|
|
|
|
|
|
|
|
#################
|
|
|
|
# META-LANGUAGE #
|
|
|
|
#################
|
|
|
|
|
|
|
|
sub alias {
|
|
|
|
my $alias;
|
|
|
|
|
|
|
|
($foo, $alias) = split(/\s/, $line);
|
|
|
|
($alias, $command) = split(/=/, $alias);
|
|
|
|
&message("alias: $alias, command: $command") if ($verbose > 2);
|
2002-02-19 05:02:23 +00:00
|
|
|
$aliases{'@' . $alias} = '@' . $command;
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub macro {
|
2002-02-05 04:52:38 +00:00
|
|
|
$line =~ s/\@macro\s+?(.*?)\{(.*?)\}/\1,\2/;
|
2002-02-02 04:55:52 +00:00
|
|
|
($macro, $macroargs) = split(/,/, $line);
|
|
|
|
$macro = &trim($macro);
|
|
|
|
$macros{$macro} = $macro;
|
|
|
|
$macrotext = '';
|
|
|
|
$inmacro = 1;
|
2002-02-05 04:52:38 +00:00
|
|
|
&message("adding macro $macro") if ($verbose > 2);
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# load custom @-commands
|
|
|
|
#
|
|
|
|
sub definfoenclose {
|
|
|
|
my ($name,
|
|
|
|
$prefix,
|
|
|
|
$suffix,
|
|
|
|
$key,
|
|
|
|
$replacement);
|
2002-02-19 05:02:23 +00:00
|
|
|
|
2002-02-02 04:55:52 +00:00
|
|
|
$line =~ s/\@definfoenclose\s+//;
|
|
|
|
($name, $prefix, $suffix) = split(/,/, $line);
|
|
|
|
$replacement = $prefix. ',' . $suffix;
|
2002-02-05 04:52:38 +00:00
|
|
|
$definfos{$name} = $replacement;
|
2002-02-19 05:02:23 +00:00
|
|
|
&message("custom definfoenclosure: $name, $replacement") if ($verbose > 2);
|
2002-02-02 04:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
####################
|
|
|
|
# SUPPORT ROUTINES #
|
|
|
|
####################
|
|
|
|
|
|
|
|
sub bracketsmatch {
|
|
|
|
my $bline = ' ' . $_[0] . ' ';
|
2002-02-16 09:24:36 +00:00
|
|
|
$bline =~ s/\@\{//g;
|
|
|
|
$bline =~ s/\@\}//g;
|
2002-02-02 04:55:52 +00:00
|
|
|
my $left = scalar split(/\{/, $bline) - 1;
|
|
|
|
my $right = scalar split(/\}/, $bline) - 1;
|
|
|
|
if ($right == $left) {
|
|
|
|
$badbracketlines = 0;
|
|
|
|
$badbracketstartline = $currentline + 1
|
|
|
|
} else {
|
|
|
|
$badbracketlines++;
|
|
|
|
&message("unmatched \{\} (left: $left, right: $right) on line $line") if ($verbose > 1);
|
2002-02-16 09:24:36 +00:00
|
|
|
if ($badbracketlines >= $maxrunonlines) {
|
2002-02-02 04:55:52 +00:00
|
|
|
&raiseerror("Mismatched brackets starting on line $badbracketstartline: $line");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ($right == $left);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub trimline {
|
|
|
|
$line = &trim($line);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub trim {
|
|
|
|
my $temp = $_[0];
|
|
|
|
|
|
|
|
$temp =~ s/^\s+//g;
|
|
|
|
$temp =~ s/\s+$//g;
|
|
|
|
return $temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub raiseerror {
|
|
|
|
my $errmsg = "ERROR: $currentfile $currentline $_[0]\n";
|
|
|
|
print STDERR $errmsg;
|
|
|
|
$errors++;
|
|
|
|
if (($maxerrors) and ($errors >= $maxerrors)) {
|
|
|
|
print STDERR "aborting after $errors errors.\n";
|
|
|
|
&writefile;
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub message {
|
|
|
|
my $message;
|
|
|
|
$message = $_[0];
|
|
|
|
|
|
|
|
if ($logfile) {
|
|
|
|
print $logfh "$message\n";
|
|
|
|
} else {
|
|
|
|
print "$message\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub version {
|
2002-05-05 21:58:38 +00:00
|
|
|
print "texi2db version $VERSION\n";
|
2002-02-02 04:55:52 +00:00
|
|
|
print "Copyright (c) 2002 David Merrill \<david\@lupercalia.net\>.\n";
|
|
|
|
print "\n";
|
2002-05-05 22:26:42 +00:00
|
|
|
print "Converts a Texinfo file into DocBook XML.\n";
|
2002-02-02 04:55:52 +00:00
|
|
|
print "\n";
|
2002-02-15 06:51:11 +00:00
|
|
|
print "This is free software; see the source for copying conditions. There is no\n";
|
2002-02-02 04:55:52 +00:00
|
|
|
print "warranty; not even for merchantability or fitness for a particular purpose.\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
sub usage {
|
|
|
|
&version;
|
|
|
|
print "\n";
|
2002-05-05 21:58:38 +00:00
|
|
|
print "Usage: texi2db [OPTIONS]... [FILE]\n";
|
2002-02-07 07:34:47 +00:00
|
|
|
print "-i, --include HTML|INFO|TEX\n";
|
|
|
|
print " include the specified text.\n";
|
2002-02-02 04:55:52 +00:00
|
|
|
print "-f, --file FILE read from file rather than STDIN.\n";
|
|
|
|
print "-o, --output-to FILE write to file rather than STDOUT.\n";
|
|
|
|
print "-l, --log-to FILE write status messages to file rather than STDOUT.\n";
|
2002-02-16 14:33:24 +00:00
|
|
|
print "-L, --runon set runon line limit (default=20)\n";
|
2002-02-02 04:55:52 +00:00
|
|
|
print "-v, --verbose show diagnostic output.\n";
|
|
|
|
print " use twice for lots of detail.\n";
|
|
|
|
print " use thrice for insane amounts of detail.\n";
|
2002-02-18 09:04:56 +00:00
|
|
|
print "-e, --max-errors MAX abort after this many errors. Default is 1.\n";
|
2002-02-02 04:55:52 +00:00
|
|
|
print " use '--max-errors 0' to disable.\n";
|
2002-02-15 06:51:11 +00:00
|
|
|
print "-h, --help show this usage message and exit.\n";
|
2002-05-05 22:26:42 +00:00
|
|
|
print "-V, --version show the program version and exit.\n";
|
2002-02-02 04:55:52 +00:00
|
|
|
exit($error);
|
|
|
|
}
|
|
|
|
|
|
|
|
__END__
|
2002-02-05 04:52:38 +00:00
|
|
|
<?xml version='1.0'?>
|
2002-02-15 14:30:00 +00:00
|
|
|
<!DOCTYPE article PUBLIC '-//OASIS//DTD DocBook XML V4.1.2//EN'
|
|
|
|
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
|
|
|
|
<!ENTITY hellip "…">
|
|
|
|
<!ENTITY Oslash "Ø">
|
|
|
|
]>
|
2002-02-02 04:55:52 +00:00
|
|
|
|
2002-05-25 15:32:11 +00:00
|
|
|
<article lang="%%LANG">
|
2002-02-15 14:30:00 +00:00
|
|
|
<articleinfo>
|
2002-02-02 04:55:52 +00:00
|
|
|
<title>%%TITLE</title>
|
2002-02-15 14:30:00 +00:00
|
|
|
<abstract>%%ABSTRACT</abstract>
|
|
|
|
</articleinfo>
|
2002-02-02 04:55:52 +00:00
|
|
|
|