98

Is there a way to make Latexmk invoke makeglossaries (part of the glossaries package)?

Specifically I want to use latexmk to compile a LaTeX document that uses the glossaries package to produce a glossary. Currently I'm using this rather clumsy sequence of commands:

makeglossaries document
latexmk -pdf document.tex
makeglossaries document
latexmk -pdf document.tex

The first run of makeglossaries is required to produce files that the glossaries package needs, or otherwise causes latexmk to fail, but there's still no data in the (non-existant) .aux file, so that first makeglossaries invocation produces nothing (except for an empty file).

So, how to do this using latexmk alone (and let that deal with invoking makeglossaries at the right time)?

lockstep
  • 250,273
Giel
  • 1,753

7 Answers7

101

At Hans-Peter E. Kristiansen’s request, I provide another answer, extending the one given by kay102.

Add the following lines to some latexmk initialization file (e.g., on Linux systems, ~/.latexmkrc):

add_cus_dep('glo', 'gls', 0, 'run_makeglossaries');
add_cus_dep('acn', 'acr', 0, 'run_makeglossaries');

sub run_makeglossaries { my ($base_name, $path) = fileparse( $_[0] ); #handle -outdir param by splitting path and file, ... pushd $path; # ... cd-ing into folder first, then running makeglossaries ...

if ( $silent ) {
    system "makeglossaries -q '$base_name'"; #unix
    # system "makeglossaries", "-q", "$base_name"; #windows
}
else {
    system "makeglossaries '$base_name'"; #unix
    # system "makeglossaries", "$base_name"; #windows
};

popd; # ... and cd-ing back again

}

As a consequence, if latexmk is invoked with the -silent option makeglossaries will be silent, too.

Moreover, add

push @generated_exts, 'glo', 'gls', 'glg';
push @generated_exts, 'acn', 'acr', 'alg';
$clean_ext .= ' %R.ist %R.xdy';

to update the cleanup functionality of latexmk appropriately.

mhp
  • 8,692
  • Cool - I am assuming that you find that kay102's answer is the best(however marginal). Can you improve this answer by adding extension from glossaries to remove with the -c or -C option? or is this bad for some reason? – hpekristiansen Feb 12 '12 at 20:32
  • @Hans-Peter E. Kristiansen: I’ve extended my answer accordingly. – mhp Feb 12 '12 at 21:10
  • Thanks - just what I needed. Bounty coming up when grace period is over. – hpekristiansen Feb 12 '12 at 21:28
  • Now the only file(except .tex) that is not removed by -C option, is the .bbl file. Should I add push @generated_exts, 'bbl'; or $clean_ext .= ' %R.bbl'; to my latexmkrc? – hpekristiansen Feb 12 '12 at 21:58
  • 1
    @Hans-Peter E. Kristiansen: The .bbl file isn’t related to the glossaries package. So it could be worth posing your comment as a regular question. (Most probably, you need $bibtex_use = 2;.) – mhp Feb 12 '12 at 22:16
  • 5
    On Windows, with MikTeX or TeXLive, the two commands should be system "makeglossaries", "-q", $_[0]; and system "makeglossaries", $_[0];... – Paul Gaborit Jun 15 '16 at 22:46
  • 1
    I don't know why your answer make my cross reference (\ref,\cite) not work, but @caramdir's answer works perfect for me. – user19832 Sep 20 '16 at 03:15
  • Is it possible to add comments to the latexmkrc file? Should they be preceded by % or #? I just want to reference this url in my latexmkrc file. Thanks. – tommy.carstensen Dec 01 '17 at 15:49
  • 2
    Like @PaulGaborit said, the window-specific version should not have the single quotes around $_[0]. Is there a way to have a if-then-else condition to detect platform and apply the rule accordingly without further manual intervention? – Dr Krishnakumar Gopalakrishnan Dec 25 '18 at 19:03
  • What is the file name on Windows and where do I find it? – Thomas Weller Apr 08 '21 at 14:04
  • @tommy.carstensen It's #. – Mouagip Sep 16 '21 at 13:05
66

You need to write a configuration file that tells latexmk which files are interesting for the glossary and how to handle them. Fortunately, the author provides some sample rc files.

Putting

add_cus_dep('glo', 'gls', 0, 'makeglo2gls');
sub makeglo2gls {
    system("makeindex -s '$_[0]'.ist -t '$_[0]'.glg -o '$_[0]'.gls '$_[0]'.glo");
}

in ~/.latexmkrc (globally in your home directory) or ./latexmkrc (locally in your document directory) should do the trick.

Caramdir
  • 89,023
  • 26
  • 255
  • 291
16

You can also let latexmk call makeglossaries directly by adding the following to your latexmkrc file (in my case I had to add it to $HOME/.latexmkrc):

add_cus_dep('glo', 'gls', 0, 'makeglossaries');
add_cus_dep('acn', 'acr', 0, 'makeglossaries');

sub makeglossaries {
    system "makeglossaries $_[0]";
    if ( -z "$_[0].glo" ) {
        open GLS, ">$_[0].gls";
        close GLS;
    }
    return 0;
}
  • 1
    With the current version of the makeglossaries program, testing for empty .glo and .acn files isn’t necessary any longer. – mhp Jan 10 '12 at 19:34
  • But this seems to be the only working solution for older makeglossaries versions and empty .glos ... – ejoerns Apr 21 '14 at 00:47
12

A lightweight solution is adding

add_cus_dep('glo', 'gls', 0, 'makeglo2gls');
add_cus_dep('acn', 'acr', 0, 'makeglo2gls');
sub makeglo2gls {
        system("makeglossaries $_[0]");
}

to your .latexmk file.

kay102
  • 231
12

My sources and generated files are in separated directories. Running mhp's solution I got the error: (require "doc.xdy") ERROR: Could not find file "doc.xdy". Then I extended the solution to:

file: conf/glossaries.latexmk
-----------------------------
print("LATEXMK: Glossaries Módule...\n");

use File::Basename;

add_cus_dep('glo', 'gls', 0, 'run_makeglossaries');
add_cus_dep('acn', 'acr', 0, 'run_makeglossaries');

sub run_makeglossaries {
   $dir = dirname($_[0]);
   $file = basename($_[0]);
   if ( $silent ) {
      system "makeglossaries -q -d '$dir' '$file'";
   }
   else {
      system "makeglossaries -d '$dir' '$file'";
   };
}

push @generated_exts, 'glo', 'gls', 'glg';
push @generated_exts, 'acn', 'acr', 'alg';
$clean_ext .= ' %R.ist %R.xdy';

Then I run as:

cd src
latexmk \
  -f -pdf -bibtex-cond \
  -r "../conf/glossaries.latexmk" \
  -auxdir=../.build -outdir=../.build \
  -pdflatex="xelatex -interaction=nonstopmode -synctex=1 %O %S" doc
Lucas
  • 221
  • 1
    What does this do? -r "../conf/glossaries.latexmk"? – tommy.carstensen Dec 01 '17 at 15:55
  • @tommy.carstensen Specifies the configuration to throw to latexmk. In this case he is not using the system-wide settings but rather specific settings for this particular project / document / whatever. – flindeberg Nov 15 '18 at 09:51
  • This works if your auxiliary files are within a different directory, which was my original problem. – Max Dec 05 '19 at 13:10
10

The current version of the glossary/glossaries sample latexmkrc file on CTAN http://mirrors.ctan.org/support/latexmk/example_rcfiles/glossaries_latexmkrc contains

# This shows how to use the glossaries package
# (http://www.ctan.org/pkg/glossaries) and the glossaries-extra package
# (http://www.ctan.org/pkg/glossaries-extra) with latexmk.

N.B. There is also the OBSOLETE glossary package

(http://www.ctan.org/pkg/glossary), which has some differences. See item 2.

1. If you use the glossaries or the glossaries-extra package, then you can use:

add_cus_dep( 'acn', 'acr', 0, 'makeglossaries' ); add_cus_dep( 'glo', 'gls', 0, 'makeglossaries' ); $clean_ext .= " acr acn alg glo gls glg";

sub makeglossaries { my ($base_name, $path) = fileparse( $_[0] ); my @args = ( "-q", "-d", $path, $base_name ); if ($silent) { unshift @args, "-q"; } return system "makeglossaries", "-d", $path, $base_name; }

2. The above will tend to run makeglossaries more often than needed, since

each out of date file will trigger the use of makeglossaries, even

though makeglossaries makes all the glossaries. The following solution

solves this, but at the expense of not having the convenience that

makeglossaries can change how it makes the glossaries depending on the

settings of the glossaries package.

A better solution will need more advanced work.

add_cus_dep( 'acn', 'acr', 0, 'makeglossaries' );

add_cus_dep( 'glo', 'gls', 0, 'makeglossaries' );

$clean_ext .= " acr acn alg glo gls glg";

sub makeglossaries {

my @args = ( "-s", "$_[0].ist", "-t", "$$Psource.ilg",

"-o", $$Pdest, $$Psource );

if ($silent) { unshift @args, "-q"; }

return system "makeindex", @args;

}

However, the makeglossaries subroutine from the glossaries_latexmkrc example is flawed.

  1. The initial definition of @args, in line two, should not contain -q, since it is added to @args in line 3 via unshift iff $silent.
  2. The @args array is not used in the final line of the subroutine

A corrected version of the makeglossaries is

sub makeglossaries {
     my ($base_name, $path) = fileparse( $_[0] );
     my @args = ( "-d", $path, $base_name );
     if ($silent) { unshift @args, "-q"; }
     return system "makeglossaries", @args;
}

There was an older glossary_latexmkrc that read

add_cus_dep( 'acn', 'acr', 0, 'makeglossaries' );
add_cus_dep( 'glo', 'gls', 0, 'makeglossaries' );
$clean_ext .= " acr acn alg glo gls glg";
sub makeglossaries {
  my ($base_name, $path) = fileparse( $_[0] );
  pushd $path;
  my $return = system "makeglossaries", $base_name;
  popd;
  return $return;
}

This also resolves the quoting issues on Windows mentioned (and resolved) in Oliver's answer for me.

Flow
  • 1,013
moewe
  • 175,683
  • 1
    Yes the sample worked right away for me as well (the other suggestions did not). – Arsenal Dec 14 '20 at 22:25
  • 2
    I use VS Code. I named this file .latexmkrc and put it into the same folder as the main TeX file. Voilá, the glossaries are there. Thanks for citing official documentation. – Thomas Weller Apr 08 '21 at 14:20
  • I also needed to install xindy, sudo apt install xindy. – Zaccharie Ramzi Dec 16 '21 at 15:03
  • The more I look at the perl code, the more I believe it is wrong. The first "-q" in line two of the makeglossaries subroutine should be removed, it is added in line three if $silent by unshift. Secondly, @args is not used in line four, when I think it should. – Flow Jun 19 '23 at 14:19
  • @Flow That's probably something you want to contact the latexmk maintainer about. – moewe Jun 19 '23 at 14:34
5

mhp's code didn't work out for me on my windows 8 machine, so i changed his code to:

add_cus_dep('glo', 'gls', 0, 'run_makeglossaries');
add_cus_dep('acn', 'acr', 0, 'run_makeglossaries');

sub run_makeglossaries {
  if ( $silent ) {
    system "makeglossaries -q $_[0]";
  }
  else {
    system "makeglossaries $_[0]";
  };
}

push @generated_exts, 'glo', 'gls', 'glg';
push @generated_exts, 'acn', 'acr', 'alg';
$clean_ext .= ' %R.ist %R.xdy';

primarily i just removed the single quotes around $_[0]. otherwise makeglossaries wasn't able to find the filename.aux file properly.

Oliver
  • 1,572
  • 1
  • 10
  • 15