4

I'm trying to set up a .latexmkrc file, to compile the document I'm creating and call both biber and bib2gls, but I'm having a problem: sometimes the rule for calling bib2gls works (by registering the rule and informing about the action), but sometimes it won't.

Here is my .latexmkrc:

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

add_cus_dep('aux', 'glstex', 0, 'run_bib2gls');

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

sub run_bib2gls {
  if ( $silent ) {
    system "bib2gls --silent --group '$_[0]'";
  } else {
    system "bib2gls --group '$_[0]'";
  };
}

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

As far as I understand, the add_cus_dep procedure links the desired input extension of a file with the desired output one, using the provided function name to do the conversion.

Is something in my code (regarding run_bib2gls) wrong?

4
  • Shouldn't there be some dependence on the .bib file? Nov 8 '17 at 15:37
  • @AndrewSwann The .bib file may not have the same base name as the .tex file (and there may be .bib files for bibtex or biblatex). The rule to run bib2gls is essentially: if the .aux file contains \glsxtr@resource and the .glstex file is older than the .aux file then run bib2gls. I don't know how latexmk deals with that kind of rule. Nov 8 '17 at 16:19
  • So I guess one needs to do same parsing of the .aux file to extract the .bib file name(s) from the \glsxtr@resource commands. Nov 8 '17 at 16:31
  • @AndrewSwann Yes and there may be multiple \glsxtr@resource{options}{base} commands within the .aux file. The second argument is the base name of the corresponding .glstex file. If src is omitted from options then the .bib file has the same base name. So \glsxtr@resource{}{sample} means bib2gls should create a file called sample.glstex using information in sample.bib whereas \glsxtr@resource{src={file1,file2}}{sample} means bib2gls should create a file called sample.glstex using information in file1.bib and file2.bib. Nov 8 '17 at 17:02
4

There are actually two issues to solve:

  1. There's a problem with latexmk so that it fails to call bib2gls if the .glstex file doesn't exist; this is the situation where the .glstex file needs to be created from scratch. The problem is latexmk doesn't recognize the message in the .log file about a missing file. (The message isn't in one of the formats programmed into latexmk.) I will fix this in the next release. Meanwhile, insert the following line in your .latexmkrc file:

    push @file_not_found, '^Package .* No file `([^\\\']*)\\\'';
    
  2. Changes in the .bib file don't get noticed by latexmk as reasons to rerun bib2gls. To solve this, the log file from bib2gls needs to be analyzed to find the name of the bib file, and then this needs to be set as a dependent. This is done by the following extension of your run_bib2gls subroutine:

    sub run_bib2gls {
      if ( $silent ) {
        my $ret = system "bib2gls --silent --group '$_[0]'";
      } else {
        my $ret = system "bib2gls --group '$_[0]'";
      };
      my ($base, $path) = fileparse( $_[0] );
      if ($path && -e "$base.glstex") {
        rename "$base.glstex", "$path$base.glstex";
      }
      # Analyze log file.
      local *LOG;
      $LOG = "$_[0].glg";
      if (!$ret && -e $LOG) {
        open LOG, "<$LOG";
        while (<LOG>) {
          if (/^Reading (.*\.bib)\s$/) {
            rdb_ensure_file( $rule, $1 );
          }
        }
        close LOG;
      }
      return $ret;
    }
    

This code also handles the case that an output directory is specified.

@NicolaTalbot: Yes, I do know about the -d option to bib2gls, but when I tried it, there were problems: On the second and subsequent calls to bib2gls from within latexmk, bib2gls tries to write the .glstex to the wrong directory. Unfortunately I haven't yet tracked down what was going wrong.

0

I know this is quite old now, but in case anyone else needs this. The following code snippet will correctly (I hope) use the -d switch for bib2gls.

sub run_bib2gls {
  my ($base, $path) = fileparse( $_[0] );
  my $silent_command = $silent ? "--silent" : "";
  if ( $path ) {
    my $ret = system("bib2gls $silent_command -d '$path' --group '$base'");
  } else {
    my $ret = system("bib2gls $silent_command --group '$_[0]'");
  };
  # Analyze log file.
  local *LOG;
  $LOG = "$_[0].glg";
  if (!$ret && -e $LOG) {
    open LOG, "<$LOG";
    while (<LOG>) {
      if (/^Reading (.*\.bib)\s$/) {
        rdb_ensure_file( $rule, $1 );
      }
    }
    close LOG;
  }
  return $ret;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy