1017 lines
26 KiB
Perl
Executable file
1017 lines
26 KiB
Perl
Executable file
#!/usr/bin/perl
|
||
# $Id: parsewiki,v 1.29 2002/10/08 17:23:05 villate Exp $
|
||
|
||
# parsewiki - Parses a text file, with formatting such as that used in a Wiki
|
||
|
||
sub Copying
|
||
{
|
||
print <<'EndTerms';
|
||
Copyright (C) 2002 Jaime Villate <villate@gnu.org>
|
||
|
||
This program is free software; you can redistribute it and/or
|
||
modify it under the terms of the GNU General Public License
|
||
as published by the Free Software Foundation; either version 2
|
||
of the License, or (at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with this program; if not, write to the Free Software
|
||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
|
||
Some of the subroutines used are based on the Use Mod Wiki script
|
||
<http://www.usemod.com/cgi-bin/wiki.pl>, version 0.92 (April 21, 2001)
|
||
by Clifford A. Adams
|
||
|
||
EndTerms
|
||
exit;
|
||
}
|
||
sub Usage
|
||
{
|
||
print STDERR <<"EndUsage";
|
||
Usage: $0 [OPTION]... [FILE]
|
||
|
||
Options:
|
||
-f, --format=FORMAT Output format; one of html, xhtml, docbook, latex.
|
||
(default html)
|
||
-T, --title=TITLE Title.
|
||
-t, --template=FILE File with a template to use instead of thestandard.
|
||
-c, --copyright Display copyright and copying permission statement.
|
||
-h, --help Show this usage summary.
|
||
|
||
FILE is a simple text file with wiki formating syntax. The result will be
|
||
sent to the Standard Output. If FILE is not given, input will be taken from
|
||
the Standard Input.
|
||
|
||
Examples:
|
||
$0 myfile.wiki
|
||
cat file.txt | $0 -fdocbook --title="An Example" >file.xml
|
||
|
||
Report bugs to <villate\@gnu.org>.
|
||
EndUsage
|
||
exit 1;
|
||
}
|
||
|
||
use strict;
|
||
use vars qw($SaveUrlIndex $UrlProtocols $UrlPattern $authorcount $figcount
|
||
$UrlProtocols2 $UrlPattern2 $ImageExtensions $FS $frontmatter
|
||
$FreeLinkPattern $IndentLimit $language $Format $Template
|
||
$title $lang $babel $LT $GT $BL $BR $firstheading $Languages
|
||
$Titles $Authors $Orgs $Addresses $Dates $Versions $Abstracts
|
||
$Figures @Title @Author @Org @Address @Date @Version @Abstract
|
||
@Figure @Language @BabelLang @Tag %SaveUrl %OpenTag %CloseTag
|
||
%OpenItem %CloseItem %Meta %LangCode $Revision $LF);
|
||
|
||
# Configuration variables and Default options
|
||
%SaveUrl = ();
|
||
$SaveUrlIndex = 0;
|
||
$authorcount = 0;
|
||
@Tag = qw(ul ol dl pre em strong code img a p dt);
|
||
%OpenItem = qw(ol <li> ul <li> dl <dd>);
|
||
%CloseItem = qw(ol </li> ul </li> dl </dd>);
|
||
$Format = 'html';
|
||
$Revision = q($Revision: 1.29 $);
|
||
|
||
my $file = &GetOpts(); # Process command line options
|
||
|
||
# Set up output format
|
||
$_ = $Format;
|
||
FORMAT:
|
||
{
|
||
if (/^html$/i) { &SetUpHTML; last FORMAT}
|
||
if (/^xhtml$/i) { &SetUpXHTML; last FORMAT}
|
||
if (/^docbook$/i) { &SetUpDB; last FORMAT}
|
||
if (/^latex$/i) { &SetUpLatex; last FORMAT}
|
||
die "$0: Unknown format \"$Format\"\n\n";
|
||
}
|
||
|
||
# Get input file
|
||
open (IN,"<$file") or die "$0: Cannot read file $file\n\n" ;
|
||
undef $/;
|
||
my $page = <IN>;
|
||
close IN;
|
||
|
||
&InitLinkPatterns();
|
||
&InitLangTables();
|
||
$page =~ s/([^\\])\\\\\r?\n/$1$FS$FS/go; # Encode paragraph breaks
|
||
$page =~ s/([^\\])\\\r?\n/$1 /g; # Join (text) lines ending in backslash
|
||
($firstheading) = ($page =~ /=\s+([^=]*)\s+=/);
|
||
if ($Format =~ /latex/i)
|
||
{
|
||
$page = &QuoteLatex1($page);
|
||
}
|
||
else
|
||
{
|
||
$page = &QuoteHtml($page);
|
||
}
|
||
$page = &CommonMarkup($page, 1, 0); # Multi-line markup
|
||
$page = &WikiLinesToHtml($page); # Line-oriented markup
|
||
|
||
# Get the title, if not defined by a command-line option
|
||
$title = $Meta{'title'} if ($Meta{'title'} && !$title);
|
||
$title = $firstheading unless $title;
|
||
$babel = $BabelLang[$language];
|
||
$lang = ' lang="' . $Meta{language} . '"' if ($Meta{language});
|
||
|
||
$_ = $Format;
|
||
FORMAT:
|
||
{
|
||
if (/^html$/i) { &SetHTMLFront; last FORMAT }
|
||
if (/^xhtml$/i) { &SetXHTMLFront; last FORMAT }
|
||
if (/^docbook$/i) { &SetDBFront; last FORMAT }
|
||
if (/^latex$/i) { &SetLatexFront }
|
||
}
|
||
|
||
$page =~ s/$FS$FS/\\\\$LF/g; # Decode \\ which are not paragraph breaks
|
||
$page =~ s/$FS(\d+)$FS/$SaveUrl{$1}/ge; # Restore saved text
|
||
$page =~ s/$FS(\d+)$FS/$SaveUrl{$1}/ge; # Restore nested saved text
|
||
|
||
# The following statement will fail if $Template has unmatched parentheses
|
||
# and will silently fail if the referred variables are undefined.
|
||
print eval("qq($Template)");
|
||
exit 0;
|
||
|
||
sub WikiLinesToHtml
|
||
{
|
||
my ($pageText) = @_;
|
||
my ($pageHtml, @htmlStack, $code, $depth, $oldCode, $oldDepth);
|
||
my ($hDepth, $oldhDepth, $index, $flag, $line);
|
||
|
||
@htmlStack = ();
|
||
$depth = 0;
|
||
$hDepth = 0;
|
||
$pageHtml = "";
|
||
$flag = 1;
|
||
$IndentLimit = 6 if ( $IndentLimit < 1);
|
||
|
||
# Process lines one-at-a-time
|
||
foreach $line (split(/\n/, $pageText))
|
||
{
|
||
# Search for meta-info lines
|
||
if ($flag > 0)
|
||
{
|
||
next if ($line =~ /^\s*$/);
|
||
if ($line =~ s/\s*(?:$BL)([^\s:]+):\s*(.+)(?:$BR)\s*$//o)
|
||
{
|
||
&StoreMeta($1, $2);
|
||
next;
|
||
}
|
||
else
|
||
{
|
||
$flag = 0;
|
||
}
|
||
}
|
||
|
||
# Process main text lines
|
||
$line .= "\n" unless ($line =~ /^\s*$/);
|
||
$oldDepth = $depth;
|
||
$depth = 0;
|
||
$oldhDepth = $hDepth;
|
||
$_ = $line;
|
||
|
||
# Process lines with special characters on the first column
|
||
CODE:
|
||
{
|
||
# Descriptive lists
|
||
if (s/^(\;+)\s*([^:]+\:?)\: */$OpenTag{dt}$2$CloseTag{dt}\n$OpenItem{dl}/)
|
||
{
|
||
$code = "dl";
|
||
$depth = length $1;
|
||
last CODE;
|
||
}
|
||
if (s/^(\:+) */$OpenTag{dt}$CloseTag{dt}\n<$OpenItem{dl}/)
|
||
{
|
||
$code = "dl";
|
||
$depth = length $1;
|
||
last CODE;
|
||
}
|
||
# Itemized lists
|
||
if (s/^(\*+) */$OpenItem{ul}/)
|
||
{
|
||
$code = "ul";
|
||
$depth = length $1;
|
||
last CODE;
|
||
}
|
||
# Ordered lists
|
||
if (s/^(\#+) */$OpenItem{ol}/)
|
||
{
|
||
$code = "ol";
|
||
$depth = length $1;
|
||
last CODE;
|
||
}
|
||
# Verbatim environment
|
||
if (/^[ \t].*\S/)
|
||
{
|
||
$code = "pre";
|
||
$depth = 1;
|
||
last CODE;
|
||
}
|
||
# Text line
|
||
if (/^[^\s\=]/)
|
||
{
|
||
$code = "p";
|
||
$depth = 1;
|
||
last CODE;
|
||
}
|
||
# Section headings
|
||
if (s/^(\=+)\s*([^\=]+)\s*\=+/&WikiHeading($1, $2)/e)
|
||
{
|
||
$hDepth = length $1;
|
||
$code = "h$depth";
|
||
last CODE;
|
||
}
|
||
# New paragraph
|
||
if (/^\s*$/)
|
||
{
|
||
$code = '';
|
||
}
|
||
}
|
||
# Close elements as needed
|
||
while (@htmlStack > $depth)
|
||
{
|
||
$oldCode = pop(@htmlStack);
|
||
if ($oldCode =~ /^[dou]l$/)
|
||
{
|
||
$pageHtml =~ s/\n$/$CloseItem{$oldCode}\n/;
|
||
}
|
||
$pageHtml .= $CloseTag{$oldCode} . "\n";
|
||
}
|
||
|
||
# Open or close new sections as needed
|
||
if ($hDepth > $oldhDepth)
|
||
{
|
||
while ($hDepth > $oldhDepth )
|
||
{
|
||
$oldhDepth++;
|
||
$pageHtml .= $OpenTag{'h'.$oldhDepth} . "\n";
|
||
$pageHtml .= $OpenItem{'h'.$oldhDepth} .
|
||
$CloseItem{'h'.$oldhDepth} . "\n"
|
||
unless ($hDepth == $oldhDepth );
|
||
}
|
||
}
|
||
elsif ($hDepth < $oldhDepth)
|
||
{
|
||
while ($hDepth <= $oldhDepth )
|
||
{
|
||
$pageHtml .= $CloseTag{'h'.$oldhDepth} . "\n";
|
||
$oldhDepth--;
|
||
}
|
||
$pageHtml .= $OpenTag{'h'.$hDepth};
|
||
}
|
||
elsif ($code =~ /h\d/)
|
||
{
|
||
$pageHtml .= $CloseTag{'h'.$hDepth} . "\n" . $OpenTag{'h'.$hDepth};
|
||
}
|
||
|
||
# Parse paragraphs and lists
|
||
if ($depth > 0)
|
||
{
|
||
$depth = $IndentLimit if ($depth > $IndentLimit);
|
||
if (@htmlStack)
|
||
{
|
||
# Non-empty stack
|
||
$oldCode = pop(@htmlStack);
|
||
if ($depth > $oldDepth)
|
||
{
|
||
# Start a nested list
|
||
push(@htmlStack, $oldCode);
|
||
$pageHtml .= "$OpenTag{$code}\n";
|
||
if (($depth - $oldDepth) > 1)
|
||
{
|
||
$pageHtml .= $OpenItem{$code} . "\n";
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ($oldCode =~ /^[dou]l$/)
|
||
{
|
||
$pageHtml =~ s/\n$/$CloseItem{$oldCode}\n/;
|
||
}
|
||
if ($oldCode ne $code)
|
||
{
|
||
$pageHtml .= "$CloseTag{$oldCode}\n$OpenTag{$code}\n";
|
||
}
|
||
}
|
||
push(@htmlStack, $code);
|
||
}
|
||
|
||
# Fill up stack as needed
|
||
while (@htmlStack < $depth)
|
||
{
|
||
push(@htmlStack, $code);
|
||
$pageHtml .= $OpenTag{$code} . "\n";
|
||
if ($code =~ /^[dou]l$/ && $depth > @htmlStack)
|
||
{
|
||
$pageHtml .= $OpenItem{$code} . "\n";
|
||
}
|
||
}
|
||
}
|
||
|
||
# Parse line-oriented common markup
|
||
unless (/^\s*$/)
|
||
{
|
||
$line = &CommonMarkup($_, 1, 2);
|
||
$line = &QuoteLatex2($line) if ($Format =~ /latex/i && $code !~ /pre/);
|
||
if ($code =~ /^[dou]l$/)
|
||
{
|
||
$line =~ s/$FS$FS/$CloseTag{p}\n$OpenTag{p}\n/go; # par. breaks
|
||
}
|
||
$pageHtml .= $line;
|
||
}
|
||
}
|
||
|
||
while (@htmlStack > 0)
|
||
{
|
||
# Clear stack
|
||
$oldCode = pop(@htmlStack);
|
||
if ($oldCode =~ /^[dou]l$/)
|
||
{
|
||
$pageHtml =~ s/\n$/$CloseItem{$oldCode}\n/;
|
||
}
|
||
$pageHtml .= $CloseTag{$oldCode} . "\n";
|
||
}
|
||
|
||
# Close open sections
|
||
while ($hDepth > 0)
|
||
{
|
||
$pageHtml .= $CloseTag{'h'.$hDepth} . "\n";
|
||
$hDepth--;
|
||
}
|
||
return $pageHtml;
|
||
}
|
||
|
||
sub CommonMarkup
|
||
{
|
||
my ($text, $useImage, $doLines) = @_;
|
||
local $_ = $text;
|
||
|
||
if ($doLines < 2)
|
||
{ # HTML tags that should be replaced before other tags are
|
||
# inserted into the text, to avoid mixing them up.
|
||
s/(?:$LT)pre$GT((.|\n)*?)$LT\/pre$GT/&StorePre($1, "pre")/igeo;
|
||
s/(?:$LT)code$GT((.|\n)*?)$LT\/code$GT/&StorePre($1, "code")/igeo;
|
||
# Note that these tags are restricted to a single line
|
||
s/(?:$LT)b$GT(.*?)$LT\/b$GT/$OpenTag{strong}$1$CloseTag{strong}/gio;
|
||
s/(?:$LT)i$GT(.*?)$LT\/i$GT/$OpenTag{em}$1$CloseTag{em}/gio;
|
||
s/(?:$LT)strong$GT(.*?)$LT\/strong$GT/$OpenTag{strong}$1$CloseTag{strong}/gio;
|
||
s/(?:$LT)em$GT(.*?)$LT\/em$GT/$OpenTag{em}$1$CloseTag{em}/gio;
|
||
s/(?:$LT)tt$GT(.*?)$LT\/tt$GT/$OpenTag{code}$1$CloseTag{code}/gio;
|
||
s/\[$UrlPattern\s+([^\]]+?)\]/&StoreBracketUrl($1, $2)/geos;
|
||
s/\[$UrlPattern\]/&StoreBracketUrl($1, "")/geo;
|
||
if ($Format =~ /^html$/i)
|
||
{
|
||
s/$UrlPattern2/&StoreUrl($1, $useImage)/geo;
|
||
} else {
|
||
s/$UrlPattern2/&StoreUrl($1, 0)/geo;
|
||
}
|
||
s/\[\[$FreeLinkPattern\s+([^\]]+?)\]\]/&StoreBracketUrl($1, $2)/geo;
|
||
s/\[\[$FreeLinkPattern\]\]/&StoreUrl($1, $useImage)/geo;
|
||
}
|
||
if ($doLines)
|
||
# TO DO: these substitutions should not be made inside the "pre" environment
|
||
|
||
{ # 0 = before other tags are inserted, 1 or 2 = after that
|
||
# TO DO: The quote markup patterns avoid overlapping tags (with 5 quotes)
|
||
# by matching the inner quotes for the strong pattern.
|
||
# s/(\'*)\'\'\'(.*?)\'\'\'/$1$OpenTag{strong}$2$CloseTag{strong}/go;
|
||
s/\'\'\'(.*?)\'\'\'/&TagText($1,'strong')/ge;
|
||
s/''(.*?)''/&TagText($1,'em')/ge;
|
||
s/,,(.*?),,/&TagText($1,'code')/ge;
|
||
}
|
||
return $_;
|
||
}
|
||
|
||
sub WikiHeading
|
||
{
|
||
my ($depth, $text) = @_;
|
||
$depth = length($depth);
|
||
$depth = 5 if ($depth > 5);
|
||
return $OpenItem{'h'.$depth} . $text . $CloseItem{'h'.$depth} . "\n";
|
||
}
|
||
|
||
sub QuoteLatex1
|
||
{
|
||
my ($html) = @_;
|
||
my $text = '';
|
||
$BL = '\\\{';
|
||
$BR = '\\\}';
|
||
foreach (split(/\n/, $html))
|
||
{
|
||
if (/^\S/)
|
||
{
|
||
s/\\/\\ensuremath$FS\\backslash$FS/go;
|
||
s/\{/\\{/g;
|
||
s/\}/\\}/g;
|
||
s/$FS(\\backslash)$FS/\{$1\}/go;
|
||
}
|
||
$text .= $_ . "\n";
|
||
}
|
||
return $text;
|
||
}
|
||
|
||
sub QuoteLatex2
|
||
{
|
||
my ($html) = @_;
|
||
$_ = $html;
|
||
s/&/\\&/g;
|
||
s/#/\\#/g;
|
||
s/%/\\%/g;
|
||
s/_/\\_/g;
|
||
s/\$/\\\$/g;
|
||
s/\^/\\^{}/g;
|
||
s/~/\\~{}/g;
|
||
s/>/\\ensuremath{>}/g;
|
||
s/</\\ensuremath{<}/g;
|
||
return $_;
|
||
}
|
||
|
||
sub QuoteHtml
|
||
{
|
||
my ($html) = @_;
|
||
$html =~ s/&/&/g;
|
||
$html =~ s/</</g;
|
||
$html =~ s/>/>/g;
|
||
# $html =~ s/&([\#a-zA-Z0-9]+);/&$1;/g; # Allow character references
|
||
$LT = '<';
|
||
$GT = 'gt;';
|
||
return $html;
|
||
}
|
||
|
||
sub InitLinkPatterns
|
||
{
|
||
# Field separators are used in the URL-style patterns below.
|
||
$FS = "\xb3"; # The FS character is a superscript "3"
|
||
$LT = '<';
|
||
$GT = '>';
|
||
$BL = '{';
|
||
$BR = '}';
|
||
$LF = "\n";
|
||
|
||
# Url-style links are delimited by one of:
|
||
# 1. Whitespace (kept in output)
|
||
# 2. Left or right angle-bracket (< or >) (kept in output)
|
||
# 3. Right square-bracket (]) (kept in output)
|
||
# 4. A single double-quote (") (kept in output)
|
||
# 5. A $FS (field separator) character (kept in output)
|
||
|
||
$UrlProtocols = "http|https|ftp|afs|news|nntp|mid|cid|mailto|wais|"
|
||
. "prospero|telnet|gopher";
|
||
$UrlPattern = "((?:(?:$UrlProtocols):[^\\]\\s\"$FS]+))";
|
||
$UrlProtocols2 = "http|https|ftp";
|
||
$UrlPattern2 = "((?:(?:$UrlProtocols2):[^\\]\\s\"$FS]+))";
|
||
$ImageExtensions = "(gif|jpg|png|bmp|jpeg|ico)";
|
||
$FreeLinkPattern = "([-,.()\/'_0-9A-Za-z\xc0-\xff]+)";
|
||
}
|
||
|
||
sub InitLangTables
|
||
{
|
||
$language = 0;
|
||
$babel = 'english';
|
||
@BabelLang = qw(english spanish portuges);
|
||
%LangCode = qw(en 0 es 1 pt 2);
|
||
$Languages = 'language idioma l<>ngua';
|
||
$Titles = 'title t<>tulo t<>tulo';
|
||
$Authors = 'author autor autor';
|
||
$Orgs = 'organization organizaci<63>n organiza<7A><61>o';
|
||
$Addresses = 'address direcci<63>n endere<72>o';
|
||
$Dates = 'date fecha data';
|
||
$Versions = 'version versi<73>n vers<72>o';
|
||
$Abstracts = 'abstract resumen resumo';
|
||
$Figures = 'Figure Figura Figura';
|
||
@Language = split(/ /,$Languages);
|
||
@Title = split(/ /,$Titles);
|
||
@Author = split(/ /,$Authors);
|
||
@Org = split(/ /,$Orgs);
|
||
@Address = split(/ /,$Addresses);
|
||
@Date = split(/ /,$Dates);
|
||
@Version = split(/ /,$Versions);
|
||
@Abstract = split(/ /,$Abstracts);
|
||
@Figure = split(/ /,$Figures);
|
||
}
|
||
|
||
sub StoreMeta
|
||
{
|
||
my ($name, $content) = @_;
|
||
if ($Languages =~ /$name/i)
|
||
{
|
||
$language = $LangCode{$content} if ($LangCode{$content});
|
||
$Meta{language} = $content;
|
||
}
|
||
$content = &CommonMarkup($content, 1, 2);
|
||
$content = &QuoteLatex2($content) if ($Format =~ /latex/i);
|
||
$content =~ s/$FS(\d+)$FS/$SaveUrl{$1}/ge; # Restore saved text
|
||
$content =~ s/$FS(\d+)$FS/$SaveUrl{$1}/ge; # Restore nested saved text
|
||
META:
|
||
{
|
||
if ($Titles =~ /$name/i)
|
||
{
|
||
$Meta{title} = $content;
|
||
next META;
|
||
}
|
||
if ($Authors =~ /$name/i)
|
||
{
|
||
$Meta{author}[$authorcount] = $content;
|
||
$Meta{organization}[$authorcount] = '';
|
||
$Meta{address}[$authorcount] = '';
|
||
$authorcount++;
|
||
next META;
|
||
}
|
||
if ($Orgs =~ /$name/i)
|
||
{
|
||
$authorcount = 1 if ($authorcount < 1);
|
||
$Meta{organization}[$authorcount-1] = $content;
|
||
next META;
|
||
}
|
||
if ($Addresses =~ /$name/i)
|
||
{
|
||
$authorcount = 1 if ($authorcount < 1);
|
||
$Meta{address}[$authorcount-1] = $content;
|
||
next META;
|
||
}
|
||
if ($Dates =~ /$name/i)
|
||
{
|
||
$Meta{date} = $content;
|
||
next META;
|
||
}
|
||
if ($Versions =~ /$name/i)
|
||
{
|
||
$Meta{version} = $content;
|
||
next META;
|
||
}
|
||
if ($Abstracts =~ /$name/i)
|
||
{
|
||
$content =~ s/$FS$FS/$CloseTag{p}\n$OpenTag{p}\n/go; # par. breaks
|
||
$Meta{abstract} = $content;
|
||
next META;
|
||
}
|
||
$Meta{lc($name)} = $content;
|
||
}
|
||
return '';
|
||
}
|
||
|
||
sub TagText
|
||
{
|
||
my ($text, $element) = @_;
|
||
my $result;
|
||
if ($Format =~ /latex/i)
|
||
{
|
||
$_ = $text;
|
||
LOOP:
|
||
{
|
||
if (/\G([^$FS]+)/goc)
|
||
{
|
||
$result .= "$OpenTag{$element}$1$CloseTag{$element}";
|
||
redo LOOP;
|
||
}
|
||
if (/\G$FS(\d+)$FS/goc)
|
||
{
|
||
$result .= "$FS$1$FS";
|
||
&TagURL($1,$element);
|
||
redo LOOP;
|
||
}
|
||
return $result;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$result = $OpenTag{$element} . $text . $CloseTag{$element};
|
||
return $result;
|
||
}
|
||
}
|
||
|
||
sub TagURL
|
||
{
|
||
my ($index, $element) = @_;
|
||
$SaveUrl{$index} =~ s/(\\href\{[^\}]*\})\{([^\}]*)\}/$1\{$OpenTag{$element}$2$CloseTag{$element}\}/;
|
||
return $FS . $index . $FS;
|
||
}
|
||
|
||
sub StoreRaw
|
||
{
|
||
my ($html) = @_;
|
||
|
||
$SaveUrl{$SaveUrlIndex} = $html;
|
||
return $FS . $SaveUrlIndex++ . $FS;
|
||
}
|
||
|
||
sub StoreUrl
|
||
{
|
||
my ($name, $useImage) = @_;
|
||
my ($link, $extra);
|
||
|
||
($link, $extra) = &UrlLink($name, $useImage);
|
||
# Next line ensures no empty links are stored
|
||
$link = &StoreRaw($link) if ($link ne "");
|
||
return $link . $extra;
|
||
}
|
||
|
||
sub UrlLink
|
||
{
|
||
my ($rawname, $useImage) = @_;
|
||
my ($name, $punct, $format, $text);
|
||
($name, $punct) = &SplitUrlPunct($rawname);
|
||
$text = $name;
|
||
$text = &QuoteLatex2($text) if ($Format =~ /latex/i);
|
||
if ($useImage && ($name =~ /\.$ImageExtensions$/))
|
||
{
|
||
$name =~ /\.([^\.]+)$/;
|
||
$format = uc($1);
|
||
$name =~ s/\.[^\.]+$// if ($Format =~ /latex/i);
|
||
return (eval("qq($OpenTag{img})"), $punct);
|
||
}
|
||
return (eval("qq($OpenTag{a})") . $text . $CloseTag{'a'}, $punct);
|
||
}
|
||
|
||
sub StoreBracketUrl
|
||
{
|
||
my ($name, $text) = @_;
|
||
$text = $name if ($text eq "");
|
||
$text = &QuoteLatex2($text) if ($Format =~ /latex/i);
|
||
return &StoreRaw(eval("qq($OpenTag{a})") . $text . $CloseTag{'a'});
|
||
}
|
||
|
||
sub SplitUrlPunct
|
||
{
|
||
my ($url) = @_;
|
||
my ($punct);
|
||
$url =~ s/\</</g;
|
||
$url =~ s/\>/>/g;
|
||
$url =~ s/\&/&/g;
|
||
$punct = "";
|
||
($punct) = ($url =~ /([^a-zA-Z0-9\/\xc0-\xff\%\#\?\&\+\_\~]+)$/);
|
||
$url =~ s/([^a-zA-Z0-9\/\xc0-\xff\%\#\?\&\+\_\~]+)$//;
|
||
unless ($Format =~ /latex/i)
|
||
{
|
||
$url =~ s/\&/&/g;
|
||
$punct =~ s/</</g;
|
||
$punct =~ s/>/>/g;
|
||
}
|
||
return ($url, $punct);
|
||
}
|
||
|
||
sub SetUpHTML
|
||
{
|
||
my $index;
|
||
my @htmltag = @Tag;
|
||
foreach $index (0..$#Tag)
|
||
{
|
||
$OpenTag{$Tag[$index]} = '<' . $htmltag[$index] . '>';
|
||
$CloseTag{$Tag[$index]} = '</' . $htmltag[$index] . '>';
|
||
}
|
||
$OpenTag{img} = '<img src="$name" alt="$name">';
|
||
$OpenTag{a} = '<a href="$name">';
|
||
%OpenItem = qw(ol <li><p> ul <li><p> dl <dd><p>);
|
||
%CloseItem = qw(ol </p></li> ul </p></li> dl </p></dd>);
|
||
foreach $index (1..5)
|
||
{
|
||
$OpenTag{'h'.$index} = '';
|
||
$CloseTag{'h'.$index} = '';
|
||
$OpenItem{'h'.$index} = '<h' . ($index+1) . '>';
|
||
$CloseItem{'h'.$index} = '</h' . ($index+1) . '>';
|
||
}
|
||
unless ($Template)
|
||
{
|
||
$Template = <<' EndHTML';
|
||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||
"http://www.w3.org/TR/html4/strict.dtd">
|
||
<html$lang>
|
||
<head>
|
||
<!-- Created by parsewiki $Revision -->
|
||
<title>$title</title>
|
||
</head>
|
||
<body>
|
||
$frontmatter
|
||
$page
|
||
</body>
|
||
</html>
|
||
EndHTML
|
||
}
|
||
}
|
||
|
||
sub SetUpXHTML
|
||
{
|
||
my $index;
|
||
my @xhtmltag = @Tag;
|
||
foreach $index (0..$#Tag)
|
||
{
|
||
$OpenTag{$Tag[$index]} = '<' . $xhtmltag[$index] . '>';
|
||
$CloseTag{$Tag[$index]} = '</' . $xhtmltag[$index] . '>';
|
||
}
|
||
$OpenTag{img} = '<img src="$name" alt="$name" />';
|
||
$OpenTag{a} = '<a href="$name">';
|
||
%OpenItem = qw(ol <li><p> ul <li><p> dl <dd><p>);
|
||
%CloseItem = qw(ol </p></li> ul </p></li> dl </p></dd>);
|
||
foreach $index (1..5)
|
||
{
|
||
$OpenTag{'h'.$index} = '';
|
||
$CloseTag{'h'.$index} = '';
|
||
$OpenItem{'h'.$index} = '<h' . ($index+1) . '>';
|
||
$CloseItem{'h'.$index} = '</h' . ($index+1) . '>';
|
||
}
|
||
unless ($Template)
|
||
{
|
||
$Template = <<' EndXHTML';
|
||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
<html$lang>
|
||
<head>
|
||
<!-- Created by parsewiki $Revision -->
|
||
<title>$title</title>
|
||
</head>
|
||
<body>
|
||
$frontmatter
|
||
$page
|
||
</body>
|
||
</html>
|
||
EndXHTML
|
||
}
|
||
}
|
||
|
||
sub SetUpDB
|
||
{
|
||
my $index;
|
||
my @dbtag = qw(itemizedlist orderedlist variablelist programlisting
|
||
emphasis emphasis literal inlinegraphic ulink para term);
|
||
foreach $index (0..$#Tag)
|
||
{
|
||
$OpenTag{$Tag[$index]} = '<' . $dbtag[$index] . '>';
|
||
$CloseTag{$Tag[$index]} = '</' . $dbtag[$index] . '>';
|
||
}
|
||
$OpenTag{dt} = '<varlistentry><term>';
|
||
$OpenTag{strong} = '<emphasis role="bold">';
|
||
$OpenTag{img} = '<inlinegraphic fileref="$name" format="$format" />';
|
||
$OpenTag{a} = '<ulink url="$name">';
|
||
%OpenItem = qw(ol <listitem><para> ul <listitem><para>
|
||
dl <listitem><para>);
|
||
%CloseItem = qw(ol </para></listitem> ul </para></listitem>
|
||
dl </para></listitem></varlistentry>);
|
||
foreach $index (1..5)
|
||
{
|
||
$OpenTag{'h'.$index} = '<sect' . $index . '>';
|
||
$CloseTag{'h'.$index} = '</sect' . $index . '>';
|
||
$OpenItem{'h'.$index} = '<title>';
|
||
$CloseItem{'h'.$index} = '</title>';
|
||
}
|
||
unless ($Template)
|
||
{
|
||
$Template = <<' EndDB';
|
||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||
"http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd" >
|
||
<!-- Created by parsewiki $Revision -->
|
||
<article$lang>
|
||
<articleinfo>
|
||
$frontmatter
|
||
</articleinfo>
|
||
$page
|
||
</article>
|
||
EndDB
|
||
}
|
||
}
|
||
|
||
sub SetUpLatex
|
||
{
|
||
my $index;
|
||
@Tag = qw(ul ol dl pre em strong code img a p dt);
|
||
my @latextag = qw(itemize enumerate description verbatim emph textbf
|
||
texttt);
|
||
foreach $index (0..2)
|
||
{
|
||
$OpenTag{$Tag[$index]} = "\\begin\{" . $latextag[$index] . '}';
|
||
$CloseTag{$Tag[$index]} = "\\end\{" . $latextag[$index] . '}';
|
||
}
|
||
foreach $index (4..8)
|
||
{
|
||
$OpenTag{$Tag[$index]} = "\\$latextag[$index]\{";
|
||
$CloseTag{$Tag[$index]} = "\}";
|
||
}
|
||
$OpenTag{p} = '';
|
||
$CloseTag{p} = '';
|
||
$OpenTag{dt} = '\item[';
|
||
$CloseTag{dt} = ']';
|
||
$OpenTag{pre} = '\begin{small}\begin{verbatim}';
|
||
$CloseTag{pre} = '\end{verbatim}\end{small}';
|
||
$OpenTag{img} = '\\\\includegraphics\{$name\}';
|
||
$OpenTag{a} = '\\\\href\{$name\}\{';
|
||
$CloseTag{a} = '}';
|
||
%OpenItem = ('ol', '\item ', 'ul', '\item ', 'dl', '');
|
||
%CloseItem = ('ol', '', 'ul', '', 'dl', '');
|
||
$OpenItem{h1} = '\section{';
|
||
$OpenItem{h2} = '\subsection{';
|
||
$OpenItem{h3} = '\subsubsection{';
|
||
$OpenItem{h4} = '\paragraph{';
|
||
$OpenItem{h5} = '\subparagraph{';
|
||
foreach $index (1..5)
|
||
{
|
||
$OpenTag{'h'.$index} = '';
|
||
$CloseTag{'h'.$index} = '';
|
||
$CloseItem{'h'.$index} = '}';
|
||
}
|
||
unless ($Template)
|
||
{
|
||
$Template = <<' EndLatex';
|
||
% Created by parsewiki $Revision
|
||
\\documentclass\[12pt,a4paper\]\{article\}
|
||
\\usepackage\[latin1\]\{inputenc\}
|
||
\\usepackage\[$babel\]\{babel\}
|
||
\\usepackage\{graphicx\}
|
||
\\usepackage\[colorlinks=true,urlcolor=blue\]\{hyperref\}
|
||
\\setlength\{\\oddsidemargin\}\{9pt\}
|
||
\\setlength\{\\textwidth\}\{425pt\}
|
||
\\setlength\{\\evensidemargin\}\{23pt\}
|
||
\\setlength\{\\topmargin\}\{28pt\}
|
||
\\setlength\{\\headheight\}\{17pt\}
|
||
\\setlength\{\\headsep\}\{14pt\}
|
||
\\setlength\{\\textheight\}\{45\\baselineskip\}
|
||
\\setlength\{\\footskip\}\{26pt\}
|
||
|
||
\\begin\{document\}
|
||
$frontmatter
|
||
$page
|
||
\\end\{document\}
|
||
EndLatex
|
||
}
|
||
}
|
||
|
||
sub SetHTMLFront
|
||
{
|
||
$frontmatter .= "<h1>$title</h1>\n"
|
||
if ($title && ($title ne $firstheading));
|
||
if ($authorcount > 0)
|
||
{
|
||
for my $index (1..$authorcount)
|
||
{
|
||
$frontmatter .= "$Meta{author}[$index-1]<br>\n";
|
||
$frontmatter .= "<em>$Meta{organization}[$index-1]</em><br>\n"
|
||
if ($Meta{organization}[$index-1]);
|
||
$frontmatter .= "$Meta{address}[$index-1]<br>\n"
|
||
if ($Meta{address}[$index-1]);
|
||
}
|
||
}
|
||
$frontmatter .= "<br>$Version[$language] $Meta{version}<br>\n"
|
||
if ($Meta{version});
|
||
$frontmatter .= "<br><em>$Meta{date}</em><br>\n" if ($Meta{date});
|
||
$frontmatter = "<div align=\"center\">$frontmatter</div>\n"
|
||
if ($frontmatter);
|
||
if ($Meta{abstract})
|
||
{
|
||
$Meta{abstract} =~ s/$FS$FS/<\/p>\n<p>/g;
|
||
$frontmatter .="<blockquote>\n<p>$Meta{abstract}</p>\n</blockquote>\n";
|
||
}
|
||
$frontmatter .= "<br><p>$Meta{copyright}</p>\n"
|
||
if ($Meta{copyright});
|
||
}
|
||
|
||
sub SetXHTMLFront
|
||
{
|
||
$frontmatter = "<h1>$title</h1>\n"
|
||
if ($title && ($title ne $firstheading));
|
||
if ($authorcount > 0)
|
||
{
|
||
for my $index (1..$authorcount)
|
||
{
|
||
$frontmatter .= "$Meta{author}[$index-1]<br />\n";
|
||
$frontmatter .= "<em>$Meta{organization}[$index-1]</em><br />\n"
|
||
if ($Meta{organization}[$index-1]);
|
||
$frontmatter .= "$Meta{address}[$index-1]<br />\n"
|
||
if ($Meta{address}[$index-1]);
|
||
}
|
||
}
|
||
$frontmatter .= "<br />$Version[$language] $Meta{version}<br />\n"
|
||
if ($Meta{version});
|
||
$frontmatter .= "<br /><em>$Meta{date}</em><br />\n" if ($Meta{date});
|
||
$frontmatter = "<div align=\"center\">$frontmatter</div>\n"
|
||
if ($frontmatter);
|
||
if ($Meta{abstract})
|
||
{
|
||
$Meta{abstract} =~ s/$FS$FS/<\/p>\n<p>/g;
|
||
$frontmatter .="<blockquote>\n<p>$Meta{abstract}</p>\n</blockquote>\n";
|
||
}
|
||
$frontmatter .= "<br /><p>$Meta{copyright}</p>\n"
|
||
if ($Meta{copyright});
|
||
}
|
||
|
||
sub SetDBFront
|
||
{
|
||
$frontmatter = "<title>$title</title>\n";
|
||
if ($authorcount > 0)
|
||
{
|
||
for my $index (1..$authorcount)
|
||
{
|
||
my $affil;
|
||
$frontmatter .= "<author>\n";
|
||
$Meta{author}[$index-1] =~ /^(.*)\s(\S+)\s*$/;
|
||
$frontmatter .= "<firstname>$1</firstname>\n";
|
||
$frontmatter .= "<surname>$2</surname>\n";
|
||
$affil .= "<orgname>$Meta{organization}[$index-1]" .
|
||
"</orgname>\n" if ($Meta{organization}[$index-1]);
|
||
$affil .= "<address><street>$Meta{address}[$index-1]</street></address>\n"
|
||
if ($Meta{address}[$index-1]);
|
||
$frontmatter .= "<affiliation>\n$affil\n</affiliation>\n"
|
||
if ($affil);
|
||
$frontmatter .= "</author>\n";
|
||
}
|
||
}
|
||
if ($Meta{version})
|
||
{
|
||
$frontmatter .= "<revhistory>\n<revision><revnumber>$Meta{version}"
|
||
. "</revnumber>";
|
||
$frontmatter .= "<date>$Meta{date}</date>" if ($Meta{date});
|
||
$frontmatter .= "</revision>\n</revhistory>\n";
|
||
}
|
||
else
|
||
{
|
||
$frontmatter .= "<date>$Meta{date}</date>\n" if ($Meta{date});
|
||
}
|
||
if ($Meta{abstract})
|
||
{
|
||
$Meta{abstract} =~ s/$FS$FS/<\/para>\n<para>/g;
|
||
$frontmatter .= "<abstract>\n<para>$Meta{abstract}</para>\n</abstract>\n";
|
||
}
|
||
$frontmatter .= "<legalnotice>\n<para>$Meta{copyright}\n</para>"
|
||
. "</legalnotice>\n" if ($Meta{copyright});
|
||
}
|
||
|
||
sub SetLatexFront
|
||
{
|
||
my $copyright = 0;
|
||
if ($title && ($title ne $firstheading))
|
||
{
|
||
$frontmatter = "\\title\{$title";
|
||
if ($Meta{copyright})
|
||
{
|
||
$frontmatter .= "\n\\footnote\{$Meta{copyright}\}";
|
||
$copyright = 1;
|
||
}
|
||
$frontmatter .= "\}\n";
|
||
}
|
||
if ($authorcount > 0)
|
||
{
|
||
$frontmatter .= '\author{';
|
||
for my $index (1..$authorcount)
|
||
{
|
||
$frontmatter .= "\\\\\n" if ($index > 1);
|
||
$frontmatter .= "$Meta{author}[$index-1]";
|
||
$frontmatter .= "\\\\\n\\emph\{$Meta{organization}[$index-1]\}"
|
||
if ($Meta{organization}[$index-1]);
|
||
$frontmatter .= "\\\\\n$Meta{address}[$index-1]"
|
||
if ($Meta{address}[$index-1]);
|
||
}
|
||
$frontmatter .= "\}\n";
|
||
}
|
||
if ($Meta{date})
|
||
{
|
||
$frontmatter .= "\\date\{";
|
||
$frontmatter .= "$Version[$language] $Meta{version}, "
|
||
if ($Meta{version});
|
||
$frontmatter .= "$Meta{date}" ;
|
||
$frontmatter .= "\}\n";
|
||
}
|
||
$frontmatter .= "\\maketitle\n" if ($frontmatter);
|
||
if ($Meta{abstract})
|
||
{
|
||
$Meta{abstract} =~ s/$FS$FS/\n\n/g;
|
||
$frontmatter .= "\\begin\{abstract\}\n$Meta{abstract}\n";
|
||
$frontmatter .= "\\end\{abstract\}\n";
|
||
}
|
||
$frontmatter .= "\n$Meta{copyright}\n\n"
|
||
if ($Meta{copyright} && $copyright == 0);
|
||
|
||
}
|
||
|
||
sub ReadTemplate
|
||
{
|
||
my $file = pop;
|
||
open (IN,"<$file") or die "$0: Cannot read template file $file\n\n" ;
|
||
undef $/;
|
||
$Template = <IN>;
|
||
close IN;
|
||
}
|
||
|
||
sub GetOpts
|
||
{
|
||
my $file;
|
||
while ($_ = $ARGV[0], /^-/)
|
||
{
|
||
shift(@ARGV);
|
||
if (/^-f$/) { $Format = shift(@ARGV); next }
|
||
if (/^-f(.*)$/) { $Format = $1; next }
|
||
if (/^--format\=(.*)$/) { $Format = $1; next }
|
||
if (/^-T$/) { $title = shift(@ARGV); next }
|
||
if (/^-T(.*)$/) { $title = $1; next }
|
||
if (/^--title\=(.*)$/) { $title = $1; next }
|
||
if (/^-t$/) { &ReadTemplate(shift(@ARGV)); next }
|
||
if (/^-t(.*)$/) { &ReadTemplate($1); next }
|
||
if (/^--template\=(.*)$/) { &ReadTemplate($1); next }
|
||
if (/^(-c|--copyright)/) { &Copying; next }
|
||
if (/^(-h|--help)/) { &Usage }
|
||
}
|
||
unshift(@ARGV, '-') unless @ARGV;
|
||
&Usage if (@ARGV > 1);
|
||
$file = shift(@ARGV);
|
||
return $file;
|
||
}
|