daqana / tikzDevice

A R package for producing graphics output as PGF/TikZ code for use in TeX documents.
https://daqana.github.io/tikzDevice
132 stars 26 forks source link

Using tikzDevice in child documents in different folders: Unable to calculate metrics #143

Closed J-Moravec closed 6 years ago

J-Moravec commented 8 years ago

I got eponymous error "Tex was unable to calculate metrics...".

It is probably some linking error connected with child document in different folder and local style document.

How to reproduce:

  1. create minimal example knitr tikz file
  2. create child document with simple tikz plot and link it in the main document
  3. create empty style document and usepackage it
  4. compile

So such configuration could look like: minimal.Rtex examples/child.Rtex empty.sty

How to quickfix: put style document into child folders as well, in this case: examples/empty.sty

krlmlr commented 8 years ago

I guess the error doesn't occur if child.Rtex is in the main directory?

J-Moravec commented 8 years ago

No, this happens only when:

  1. one is using tikz as knitr device (works with PDF or PNG)
  2. one is using child document in different folder (works if they are in the same folder as style document can then be found)
  3. one is using non globally-accessible package (in this case, even empty style document)
  4. Can be repaired by manually putting style document to the same folder as child document (thus making it locally accessible)

Plus, it worked year ago. This is probably problem of knitr rather than tikzDevice, do you think I should move it there?

krlmlr commented 8 years ago

Another workaround might be to set the tikz preamble to use ../empty.sty, or to use a symlink if your system supports these. Perhaps @yihui knows a knitr-based fix?

yihui commented 8 years ago

Could you simply upload the reproducible example as a zip file here?

J-Moravec commented 8 years ago

Here it is. You can see how it was translated. First graph shows that all the translation went good as this is in the main file. The second graph shows where errors happens, you can see that in this case, part of graph was still created and thus PDF could be created as well.

minimal.zip

yihui commented 8 years ago

I see. That is a knitr issue. I don't have a good solution, though.

krlmlr commented 8 years ago

It's strange because tikz() seems to be run in the base directory since, like, forever (October 2014). What is the "base directory" for a child document?

J-Moravec commented 8 years ago

I can confirm that last year it worked. So maybe new introduction?

Base directory of child document is the directory he is in, as because when you point at something with R inside that document, the relative path starts from the same folder (if you understand me). Which is probably problem for tikz as knitr/tikzDevice as it is taking the definition of LaTeX document and translating with that. How does that actually work you know probably better than me.

yihui commented 8 years ago

I don't have time to investigate this issue closely, but I guess it was introduced by this change https://github.com/yihui/knitr/pull/1073 tikz() was called twice: once for recording the plot, and another time later for generating the LaTeX output file. I guess it ran into trouble when recording the plot since the working directory was not correct.

krlmlr commented 8 years ago

I'm not sure yihui/knitr#1073 is the cause, according to @J-Moravec all is fine for the base document but not for the child document.

I can run a bisect, but perhaps the only real fix at this time is to run tikz() from the root directory but write the output file to the base directory. This is going to be funny with raster images, too: these are external to the .tex file created by tikz() and must be in the same directory then.

krlmlr commented 7 years ago

There's the TEXINPUTS environment variable that is already set at some point in the knitr code; looks like this setting affects the rendering, but not the measurement. @J-Moravec: Could you try setting the TEXINPUTS environment variable to ".:<base-dir>:" in your child documents?

I think setting TEXINPUTS should be the responsibility of the tikzDevice. We should add a new inputDirs argument to tikz(), which sets TEXINPUTS during measurement. Need also to figure out a smooth way to use this information also for rendering.

J-Moravec commented 7 years ago

sorry, I am trying to figure out what you mean. I was looking at TEXINPUTS, but I can't seem to find a way how to set it up from latex, only bash. Do you mean this? Is there any way to do it from LaTeX or do you mean setting it up for Knitr (and if so, where in knitr?)

Thanks

krlmlr commented 7 years ago

Could you try adding Sys.setenv(TEXINPUTS = ".:<base-dir>") to the first R chunk in the child document?

J-Moravec commented 7 years ago

Ah, thank you, didn't know this R command. However, it fails to compute. Seems that setting TEXINPUTS overwrite defaults? I then get errors like this:

! LaTeX Error: File `article.cls' not found.

However, by default, TEXINPUTS are blank, as described here: http://tex.stackexchange.com/questions/93712/definition-of-the-texinputs-variable

Note that TEXINPUTS is usually not set; it takes a value as soon as a TeX program is started (by reading a set of texmf.cnf files). However, if the program finds it in the environment, it follows the rule sketched above

so combo: Sys.getenv to get current value, concatenate it and then Sys.setenv would not work (and is not working).

krlmlr commented 7 years ago

How about TEXINPUTS = ".:<base-dir>:" ? Reference: answer in the SO question you linked.

cdriveraus commented 7 years ago

I'm also having quite some trouble with this, though it is perhaps somewhat different. Tikz for child documents is looking in the /figures folder for any additional classes, preamble, etc. MWE below, just change the document class to any old class file copied under Classes folder. This behaviour can be avoided if I specify fig.path = './' but this will get pretty messy.

test.rnw

\documentclass{Classes/PhDThesisPSnPDF}
\begin{document}
<<setup, include = FALSE>>=
require(knitr)
require('tikzDevice')
opts_chunk$set(dev='tikz')
@
<<tikzchild, child='child/child.rnw'>>=
@
\end{document}

/child/child.rnw

<<>>=
  plot(1:10)
@
krlmlr commented 6 years ago

Closing due to inactivity. @cdriveraus: Could you please open a new issue if you're still interested?