I am working on a songbook in LaTeX using MusiXTeX. For that to work properly, I need to compile the document as follows:

pdflatex songbook
musixflx songbook
pdflatex songbook

Is there a way to tell LaTeXmk to add musixflx to its workflow? If so, it would be easier to work on this songbook using VimTeX, which uses LaTeXmk.

LaTeXmk has options like -bibtex, but it doesn't have a dedicated option for MusiXTeX and I don't see in the manual if I can add arbitrary commands to the workflow.

  • from what i gather (havent carefully read the manual) one possibility would be to use the possibility to give the pdflatex command.. i.e. latexmk -pdf -pdflatex="pdflatex %S; musixflx %S; pdflatex %S" . But I havent tested that, its just what came to mind skimming over the manual – Bort Aug 10 '15 at 18:22
  • @Bort You also need to add a command to delete the mx2 file before the first run of pdflatex. With that change, your solution would work. See my answer for an improvement. – John Collins Aug 10 '15 at 20:59
  • @JohnCollins ah okay. turns out not only do I not know latexmk, I also do not know musixflx. your solution is way more sophisticated – Bort Aug 10 '15 at 21:53

Here's an appropriate insertion for the latexmkrc file.

$pdflatex = 'internal musixlatex %R %O %S';
push @generated_exts,"mx2";
push @generated_exts,"mx1";

sub musixlatex {
   my $root = shift;
   # Define root filename for the mx1 and mx2 files
   # Note that $aux_dir1 includes directory separator
   #      and it equals $out_dir1 if only the out_dir is set.
   my $mx = "$aux_dir1$root";
   my @args = @_;
   if ( $pass{$rule} <= 1 ) { 
      print "======= FIRST PASS: Deleting '$mx.mx2' =======\n";
      unlink "$mx.mx2"; 
      print "====   Generating '$mx.mx1' then '$mx.mx2' ===\n";
      my $ret = system( "pdflatex @args" );
      if ($ret) { return $ret; }
      $ret = system( "musixflx $mx" );
      if ($ret) { return $ret; }
   return system( "pdflatex @args" );

The main thing is that it is necessary to delete the .mx2 file before running pdflatex for the first time. Then musixflx is run to generate a new mx2 file, and then pdflatex again.

But sometimes more than two passes through pdflatex are needed to resolve cross references and the like. So I've used a bit of trickery with an internal variable of latexmk so that the use of musixflx only happens on the first pass; this keeps the number of runs of pdflatex to the minimum.

  • Hmm, thanks, but I'm getting sh: 1: internal: not found. Any idea what may cause that? I'm using Latexmk 4.43a (2015-02-05), so internal should be implemented. – Keelan Aug 10 '15 at 21:08
  • It appears that latexmk has misinterpreted internal as a command name. The code works for me when I copy and paste it from my answer. It is possible something extra got inserted in your latexmkrc in front of the word "internal". If you don't see anything relevant, could you send me your latexmkrc file off-line (to the address in the latexmk documentation), and I'll try to reproduce your problem. – John Collins Aug 10 '15 at 21:56
  • It's odd. First: thanks, this is great, it's working from the command line. The result I gave before only happens when using VimTeX. I will look into it. Maybe it's an incompatibility, but that would then be their job. Maybe I've done something wrong in my configuration. In any case, thanks for your help! – Keelan Aug 10 '15 at 22:14
  • 1
    For reference, the VimTeX issue: github.com/lervag/vimtex/issues/212 – Keelan Aug 11 '15 at 8:02

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.