vectorgraphics / asymptote

2D & 3D TeX-Aware Vector Graphics Language
https://asymptote.sourceforge.io/
GNU General Public License v3.0
550 stars 90 forks source link

latexmk rule does not work when output-directory is not the current directory? #410

Closed user202729 closed 9 months ago

user202729 commented 9 months ago

See the issue title.

To reproduce: (just any example will work)

\documentclass{article}
\usepackage{asymptote}
\begin{document}
\begin{asy}
label("Hello world");
\end{asy}
\end{document}

then latexmk b.


I think fixing this issue isn't too hard, just patch the line

https://github.com/vectorgraphics/asymptote/blob/2b4140b09ecf2df7312f93c59dff128b1a39c222/doc/asy-latex.dtx#L497

to

    defaultfilename="\outputdir/\Jobname-\the\c@asy";^^J%

where \outputdir is the output directory (probably need to provide by user).

I'm not sure how this will interact with the existing features of \asydir and \asylatexdir.

johncbowman commented 9 months ago

Use '\asydir' for this purpose.

From latexusage.tex:

% Optional subdirectory for asy files (no spaces): \def\asydir{}

user202729 commented 9 months ago

No, that isn't sufficient to fix the issue.

Test: a.tex contains

%! TEX program = pdflatex
\documentclass{article}
\usepackage{asymptote}
\def\asydir{b}
\begin{document}
\begin{asy}
label("Hello world!");
\end{asy}
\end{document}

then run

latexmk --output-directory=b a.tex

assume directory ./b exist, it will raise error

! I can't write on file `b/a-1.asy'.

On the other hand, if directory ./b/b also exist, it will raise error

Latexmk: Missing input file 'b/a-1.pdf' (or dependence on it) from following:
  Package asymptote Warning: file `b/a-1.pdf' not found on input line 8.

and the a-1.pdf file is created in the current directory, not ./b.

The patch above is needed to move a-1.pdf inside ./b/. asydir is wrong, because it would throw a-1.asy into ./b/b which is one extra layer.

johncbowman commented 9 months ago

You didn't mention that you were trying to use latexmk --output-directory=DIR. Is there a need to support this option? The normal workflow uses asydir is to keep the figures in a separate directory, to avoid clutter, and output the dvi or pdf file in the current working directory.

user202729 commented 9 months ago

Ah, my fault, I made a typo. That's what I meant to say (I remembered to include "output-directory" in title though)

Personally I normally use VimTeX to compile things, and because I don't really need the resulting PDF other than to view it (if needed can always recompile) I set the output directory to /tmp/.vimtex_build_dir/ so the directory containing source files are not cluttered with pdf log aux etc..

But it's true that, because getting output directory from LaTeX is really hard, most programs that is related to shell-escape doesn't work properly when output-directory is nonstandard. asypictureB doesn't work properly either.

Either way, the fix seems simple enough I don't see much harm. (need some testing to see if it works properly in combination with asydir etc. though)


Edit: I see that latexmkrc_asydir has a modification, but I think that configuration is not ideal because the user would need different latexmkrc on different project (e.g. if they decide to use asydir in one project but not in another)

Edit2: Okay, I see what's going on. We need to modify latexmkrc because we don't want to enable -globalwrite, so we need to explicitly allow asy to write the PDF file in asy/, setting defaultfilename is not enough.

Nevertheless, it might be useful to include in the documentation like

If you trust the asymptote code, you can enable -globalwrite, so that the same latexmkrc can work for both the case asydir is or is not used.

and edit the line https://github.com/vectorgraphics/asymptote/blob/2b4140b09ecf2df7312f93c59dff128b1a39c222/doc/asy-latex.dtx#L497 to

    defaultfilename="\ASYoutputdir\ASYasydir\Jobname-\the\c@asy";^^J%

which would allow the code to work if the user either write asy -o output/asy/ "$_[0]" or asy -globalwrite "$_[0]".

user202729 commented 9 months ago

Okay, turns out it mostly works out of the box.

Perhaps consider adding a section to the documentation with something like:

If you want to use a custom output-directory, you need to modify latexmkrc as follows.

Assume your TeX file contains \def\asydir{asy}, and you compile with latexmk --output-directory=output/, then your latexmkrc need to have

sub asy {return system("asy -o output/asy/ '$_[0]'");}
add_cus_dep("asy","eps",0,"asy");
add_cus_dep("asy","pdf",0,"asy");
add_cus_dep("asy","tex",0,"asy");

Alternatively, use https://tex.stackexchange.com/questions/258103/latexmk-and-the-location-of-asymptotes-generated-files which allows automatically detecting the location of the asy file and the generated pdf file.