Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: 7f0c39c124
Fetching contributors…

Cannot retrieve contributors at this time

550 lines (425 sloc) 13.71 kB
#!/usr/bin/perl
# mytex -- Parsing LaTeX files with mixed greek and english and
# automatically inserting proper babel commands for the language switches.
#
# Copyright (C) 2001-2004 Christos KK Loverdos
#
# 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
#
# Author : Christos KK Loverdos (loverdos@di.uoa.gr)
# Version : 0.2.3
# Script URL: http://www.di.uoa.gr/~loverdos/software/mytex
# License URL: http://www.di.uoa.gr/~loverdos/software/gpl.txt
#
##############
#CHANGELOG #
#####################################################################
#v0.2.3 : 2004/01/09
#- Added support for the Kerkis Font Family via --usekerkis switch
#- Added LIMITATIONS heading in documentation
#v0.2.2 : 2003/10/09
#- Added support for \section, \subsection, \subsubsection in --fixcaption
#- Added the CHANGELOG part HERE
#v0.2.1
#- minor documentation fixes
#####################################################################
use Getopt::Long;
use Pod::Usage;
=head1 NAME
mytex - Parsing B<LaTeX> files with mixed greek and english and
automatically inserting proper B<babel> commands for the language switches.
The name B<mytex> has been chosen because program names like B<grtex>, B<greektex> and
variants already existed at the time of creation.
=head1 SYNOPSIS
mytex [options] [file ...]
=head1 DESCRIPTION
B<This program> allows one to write a .tex source mixing greek and
english without the need to use LaTeX commands for selecting each
language. It will read the given input tex file(s) and produce
corresponding ones with the needed language selection commands added
automatically. It will even understand B<\includeonly>, B<\include> and
B<\input> declarations.
=head1 OPTIONS
=over 8
=item B<--verbose=level>
Print debug info while running. Available levels are
0 (no output), 1, 2 and 3. The default level is 1.
=item B<--program=prg>
Which program to use (e.g. B<tex>, B<latex>, B<lambda>)
on the given files. The default is B<tex>. If you do not want anything,
just say B<--program=0>
=item B<--programtimes=n>
How many times to run program (usually latex). The default value is 1.
The option is useful when several passes are needed on the input file(s).
=item B<--shortescapes>
The program uses shorter versions of the \textgreek and \latintext macros.
At present they are \tg and \lt repsectively but in the future they should be
user-specified. The default option used is the opposite: --noshortescapes.
=item B<--babel=lang>
Which language to use when using package B<babel>.
The default is B<greek>.
It can be a comma separated list of
languages (e.g. B<greek,english>).
=item B<--asmany>
If present, it tries to match as many adjacent greek characters
as possible, including spaces and other characters given by the
B<--greekchars> option. This will drastically produce more
compact output.
=item B<--greekchars=chars>
The B<chars> given are also treated as greek. The default value is
",.():" (without the quotes)
=item B<--output=ps|pdf>
If the program used created a .dvi file, this is used to produce a .ps
(using B<dvips>) or .pdf (using B<ps2pdf>).
=item B<--cleanfiles|--nocleanfiles>
Used to deal with intermediate (including *.tex) files.
--cleanfiles is the default operation which removes any
files generated by this program.
=item B<--fixcaption=lang-before,lang-after>
Inserts a \selectlanguage{lang-before} before every \caption and
a \selectlanguage{lang-after} after every \caption{. Any of the two
can be ommited, but if it is <lang-before> then the comma is needed.
=item B<--fixchapter=lang-before,lang-after>
Like --fixcaption, but for \chapter, \section, \subsection, \subsubsection.
=item B<--fixTOC=lang>
Inserts \selectlanguage{lang} before \tableofcontents
=item B<--fixtoday=lang>
Inserts \selectlanguage{lang} before \today
=item B<--noautofixtoday>
When we do not want to automatically insert a correct \selectlanguage{}
command before \today. Otherwise, if --babel=greek then
a \selectlanguage{greek} is inserted before every \today. This insertion fixes
a bug with B<babel> that doesnot handle properly a \date for greek (it
outputs greeklish instead of greek).
=item B<--usebibtex>
Runs bibtex on the input.
After bibtex it runs twice again the user B<--program>
=item B<--usekerkis>
Uses the Kerkis Font Family, developed by A. Syropoulos and A. Tsolomitis,
reached at http://iris.math.aegean.gr/kerkis/
=back
=head1 VERSION
0.2.3
=head1 BUGS
Reported to occasionally eat parts of the preamble...
=head1 LIMITATIONS
Plenty. Supports only the ISO-8859-7 encoding, for the obvious laziness-related reasons.
=head1 DOCUMENTATION
To get an HTML version of this, use B<pod2html>
=head1 URL
http://www.di.uoa.gr/~loverdos/software/mytex
=head1 LICENSE
This software is released under the GNU Public License. You can
have a copy of it from
http://www.di.uoa.gr/~loverdos/software/gpl.txt
=head1 AUTHOR
Christos KK Loverdos (loverdos@di.uoa.gr)
=cut
$GREEK="\xA2\xB6\xB8-\xBA\xBC\xBE-\xFE";
$SUFFIX = '.my.tex';
$TEXTGREEK='\textgreek';
$LATINTEXT='\latintext';
$langescapes='';
$header =<<EOH;
% +mytex: Automatic Header Generation
\\usepackage[--LANG--]{babel}
\\usepackage[iso-8859-7]{inputenc}
--USE-KERKIS--
--LANGESCAPES--
% -mytex: Automatic Header Generation
EOH
@cleanlist=();
sub verbose
{
return if($verbose < shift);
print '****', ' 'x(4*$nesting+1);
foreach(@_)
{
print "$_";
}
print "\n";
}
sub delta
{
my ($a,$b)=@_;
return $a==0? 0 : int(100 * ($b - $a) / $a);
}
sub doFile
{
my ($file) = @_;
if(-f $file)
{
if($file !~ /$SUFFIX$/)
{
verbose 2, "Processing : $file";
return processFile($file);
}
else
{
verbose 0, "Warning: File $file seems already processed, ignoring it";
}
}
else
{
verbose 0, "Warning: $file doesnot exist.";
}
"";
}
sub fixName
{
return $_[0] if($_[0] =~ /\.tex$/);
return $_[0] . ".tex";
}
sub newName
{
fixName($_[0]) . $SUFFIX;
}
sub newNameNoTex
{
my $x = newName($_[0]);
$x =~ s/\.tex$//;
$x;
}
sub processFile
{
my ($name) = @_;
my $contents='';
open TEX, "$name";
$contents = join "", (<TEX>);
close TEX;
my $bytes_0 = length $contents;
$totalbytes_0 += $bytes_0;
# fix caption (before & after)
$contents =~ s/\\caption/\\selectlanguage{$fixcaption_before}\\caption/sg if($fixcaption_before);
$contents =~ s/(\\caption\s*\{)/$1\\selectlanguage{$fixcaption_after}/sg if($fixcaption_after);
# fix chapter (before & after)
# Added: 2003/10/09: also support for section, subsection, subsubsection
$contents =~ s/\\(chapter|(sub(sub)?)?section)/\\selectlanguage{$fixchapter_before}\\$1/sg if($fixchapter_before);
$contents =~ s/(\\(chapter|(sub(sub)?)?section)\s*\{)/$1\\selectlanguage{$fixchapter_after}/sg if($fixchapter_after);
# fix TOC (Table of Contents)
$contents =~ s/\\tableofcontents/\\selectlanguage{$fixTOC}$&/s if($fixTOC);
# fix \today
$contents =~ s/\\today/\\selectlanguage{$fixtoday}$&/sg if($fixtoday);
# remove declared <babel> support
$contents =~ s/\\usepackage(\[.+?\])?{babel}//s;
# remove declared <inputenc> support
$contents =~ s/\\usepackage(\[.+?\])?{inputenc}//s;
# v0.2.3
# remove declared <kerkis> support (to be added again if --usekerkis)
$contents =~ s/\\usepackage(\[.+?\])?{kerkis}//s;
# add <babel> and <inputenc> support (v0.2.3 and kerkis)
$contents =~ s/(.*?)(\s*\\documentclass(?:\[.+?\])?\{.+?\})(\n.+)/$1$2\n\n$header$3/s;
# handle greek text
if($asmany)
{
#$contents =~ s/([\xC1-\xFF]([0-9\xC1-\xFF\:\.\/ ]*[\xC1-\xFF])?)/$TEXTGREEK{$1}$LATINTEXT{}/sg;
$contents =~ s/([$GREEK]([0-9$GREEK$alsoGREEK ]*[$GREEK$alsoGREEK])?)/$TEXTGREEK\{$1\}$LATINTEXT\{\}/sg;
}
else
{
#$contents =~ s/([\xC1-\xFF][0-9\xC1-\xFF\:\.\/]*)/$TEXTGREEK{$1}$LATINTEXT{}/sg;
$contents =~ s/([$GREEK][0-9$GREEK$alsoGREEK]*)/$TEXTGREEK\{$1\}$LATINTEXT\{\}/sg;
}
# handle <includeonly>
if($contents =~ /\\includeonly([^{]*){([^}]+)}/mi)
{
my $pre = $`;
my $suf = $';
my $includes = $2;
$includes =~ s/\s*[%]+.*\n//g;
$includes =~ s/\n//mg;
my @includes = split ',', $includes;
my @newincludes = ();
foreach my $on(@includes)
{
my $nn = newNameNoTex($on);
verbose 2, "IncludeOnly : $on -- > $nn";
push @newincludes, $nn;
}
$includes = join ",\n", @newincludes;
$contents = "$pre\\includeonly{\n$includes}$suf";
}
# handle <input> files
sub fixInput
{
sub fixIt
{
my ($name, $what) = @_;
my $on = $name;
my $nn = newNameNoTex($on);
verbose 2, "Changing : \\$what"."{$on} --> \\$what"."{$nn}";
$on = fixName($on);
verbose 2, "Reading file : $on";
#my $newnest = $nesting + 1;
#verbose 3, "Executing :$0 --nesting $newnest $on";
#my $res = qx"$0 --verbose $verbose --nesting $newnest $on";
#chomp $res;
#verbose 1, $res;
$nesting++;
doFile $on;
$nesting--;
return $nn;
}
my ($contents) = @_;
if($contents =~ /\\input{([^}]+)}/)
{
my $nn = fixIt($1, "input");
$contents = fixInput($`) . "\\input{$nn}" . fixInput($');
}
elsif($contents =~ /\\include{([^}]+)}/)
{
my $nn = fixIt($1, "include");
$contents = fixInput($`) . "\\include{$nn}" . fixInput($');
}
return $contents;
}
$contents = fixInput($contents);
my $bytes_1 = length $contents;
$totalbytes_1 += $bytes_1;
$name = "$name$SUFFIX";
open TEX, ">$name";
print TEX $contents;
close TEX;
# add to cleanlist
push @cleanlist, "$name";
verbose 3, "Initial length: $bytes_0";
verbose 3, "Final length: $bytes_1";
verbose 1, "Writing file: $name (+", delta($bytes_0, $bytes_1), "%)";
return $name;
}
$alsoGREEK=",.():";
$program='hugelatex';
$programtimes=1;
$help=0;
$verbose=1;
$asmany=0;
$nesting=0;
$babel='greek';
$greekchars='';
$shortescapes=0;
$output='dvi';
$cleanfiles=1;
$fixcaption='';
$fixcaption_before='';
$fixcaption_after='';
$fixchapter='';
$fixchapter_before='';
$fixchapter_after='';
$fixTOC='';
$usebibtex=0; # 2002/03/03
$fixtoday=0; # 2002/03/07
$autofixtoday=1;
$usekerkis=''; # 2004/01/09
GetOptions(
'program=s' => \$program,
'programtimes=i' => \$programtimes,
'verbose:i' => \$verbose,
'help+' => \$help,
'asmany+' => \$asmany,
'nesting=i' => \$nesting,
'babel|language=s' => \$babel,
'greekchars=s' => sub { my ($name, $val) = @_; $alsoGREEK .= $val},
'shortescapes!' =>\$shortescapes,
'output=s' => \$output,
'cleanfiles!' => \$cleanfiles,
'fixcaption=s' => \$fixcaption,
'fixchapter=s' => \$fixchapter,
'fixTOC=s' => \$fixTOC,
'fixtoday=s' => \$fixtoday,
'autofixtoday!' => \$autofixtoday,
'usebibtex+' => \$usebibtex,
'usekerkis+' => \$usekerkis, # Note: not sure whether correct (haven't touched perl for a long time...)
);
($help or $#ARGV==-1) and pod2usage(-verbose => 2);
($fixcaption_before, $fixcaption_after) = split ',', $fixcaption;
($fixchapter_before, $fixchapter_after) = split ',', $fixchapter;
$usekerkis = '\\usepackage{kerkis}' if($usekerkis);
# There is a problem with \today with greek
if($autofixtoday && !$fixtoday)
{
$fixtoday = ($babel eq 'greek') ? 'greek' : 0;
}
#verbose 2, "$0 -v -p $program --nesting $nesting --babel=$babel ", ($asmany?"--asmany ":" "), (join ' ', @ARGV);
if($shortescapes)
{
$TEXTGREEK='\tg';
$LATINTEXT='\lt';
$langescapes=<<EOH;
\\newcommand{\\lt}[0]{\\latintext}
\\newcommand{\\tg}[1]{\\textgreek{#1}}
EOH
}
$header =~ s/--LANG--/$babel/;
$header =~ s/--LANGESCAPES--/$langescapes/;
$header =~ s/--USE-KERKIS--/$usekerkis/; # v0.2.3
foreach $file(@ARGV)
{
$totalbytes_0 = 0;
$totalbytes_1 = 0;
my $nn = doFile($file);
verbose 1, "$file: Total bytes read : $totalbytes_0";
verbose 1, "$nn: Total bytes written: $totalbytes_1 (+", delta($totalbytes_0, $totalbytes_1), "%)";
next if(!$program || !$nn || !$programtimes);
for(my $i=1; $i<=$programtimes; $i++)
{
verbose 1, "";
verbose 1, "Running $program on $nn, pass $i";
verbose 1, "";
system("$program $nn");
}
$nn =~ s/\.tex$//;
# use BibTeX if requested
if($usebibtex)
{
verbose 1, "";
verbose 1, "Running bibtex on $nn";
system("bibtex $nn");
verbose 1, "Running again $program after bibtex (1)";
system("$program $nn");
verbose 1, "Running again $program after bibtex (2)";
system("$program $nn");
}
push @cleanlist, "$nn.aux";
push @cleanlist, "$nn.log";
push @cleanlist, "$nn.lot";
push @cleanlist, "$nn.lof";
push @cleanlist, "$nn.toc";
push @cleanlist, "$nn.out" if($program eq 'pdflatex'); # 2002/02/27
push @cleanlist, "$nn.bbl" if($usebibtex);
push @cleanlist, "$nn.blg" if($usebibtex);
# only if a .dvi file exists
my $dvi = "$nn.dvi";
if(-f $dvi and ($output eq 'ps' or $output eq 'pdf'))
{
my $ps = "$nn.ps";
verbose 1, "";
verbose 1, "Making $ps from $dvi";
verbose 1, "";
system("dvips -o $ps $dvi");
push @cleanlist, $dvi;
if($output eq 'pdf')
{
my $pdf = "$nn.pdf";
verbose 1, "";
verbose 1, "Making $pdf from $ps";
verbose 1, "";
system("ps2pdf $ps $pdf");
push @cleanlist, $ps;
}
}
next if(!$cleanfiles);
verbose 1, "Cleaning temporaries ";
unlink @cleanlist;
}
Jump to Line
Something went wrong with that request. Please try again.