#!/usr/bin/perl # Author: Dimitri Antoniou # usage: ltags filename # handles: \label and \cite{ } with one or more arguments # fails if arguments of cite spread over more than one line # also searches in files that are \include or \input in the main file # get main LaTeX source file from command line: $mainfile = shift; # get names of included files and store them in an array open MAIN, $mainfile or die "$!" ; @mainfile=
; @allsrcfiles = map{ /^\\(?:input|include){(.*?)}/ } @mainfile; unshift @allsrcfiles, $mainfile; # loop over all source files for $srcfile (@allsrcfiles) { # if \input{fname} append .tex to fname unless ( $srcfile =~ m/\.tex/ ) { $srcfile = $srcfile . "\.tex" } open SRC, $srcfile or die "$!" ; # store contents of source file in array @texfile @texfile=; # store lines with \label and \cite (or \citeonline) in arrays @labelList = grep{ /\\label{/ } @texfile; @citeList = grep{ /\\(cite|citeonline){/ } @texfile; # see if we use an external database; if yes, store its name in $bibfile ($dbase) = grep{ /^\\bibliography{/ } @texfile; if ($dbase) { $dbase =~ m/\\bibliography{(.*?)}/; $bibfile = $1; } # write \bibitem in tags file @mrefs=(); @refs=(); @multirefs=(); foreach (@citeList) { while ( m/\\(?:cite|citeonline){(.*?)}/g ) { $refs = $1; # if \cite has more than one argument, split them: if ($refs =~ /,/) { @mrefs = split /,/, $refs; # there might be more than one \cite in a line: push (@multirefs, @mrefs); } else { @refs = ($refs); push (@multirefs, @refs); } } # in BibTeX, format is @ARTICLE{Name, }; in source file, \bibitem{Name} for $ref (@multirefs) { if ( $dbase ) { push @unsorttag, "$ref\t$bibfile\t/{$ref,/\n" } else { push @unsorttag, "$ref\t$srcfile\t/bibitem{$ref}/\n" } } } # write \label in tag file foreach (@labelList) { m/\\label{(.*?)}/; push @unsorttag, "$1\t$srcfile\t/label{$1}/\n"; } } # sort tag file; then, eliminate duplicates @sortedtag = sort @unsorttag; %seen = (); @uniqtag = grep { ! $seen{$_} ++ } @sortedtag; open(TAGS, "> tags"); print TAGS @uniqtag;