Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-file project with subfile #155

Closed
maxfl opened this issue Apr 16, 2015 · 21 comments
Closed

Multi-file project with subfile #155

maxfl opened this issue Apr 16, 2015 · 21 comments

Comments

@maxfl
Copy link

maxfl commented Apr 16, 2015

Hi, I'm used to do multi-file projects, based on subfile package. In other words each included file has its own begin/end document environment and can be compiled independently. The compilation and the compiled files happen in the root directory, even if the file itself is located in subfolder. There fore I have several questions.

  1. Is there a simple way to tell vimtex where the main file is? It would be good to have a possibility to set it from local vimrc. Or may vimtex detect \documentclass[main.tex]{subfiles} line to determine the main file?
  2. Is it possible to change the compilation root for the current file to the project root and compile the current file even when main file is set?
  3. Is it possible to view the current file's pdf even when the main file set?

Thank you in advance. Vimtex is amazing and fast.

@lervag
Copy link
Owner

lervag commented Apr 17, 2015

Hi! First, I've never heard about the subfile package. It seems like a nice idea, although it does introduce some complexities that I am not quite sure if I want to introduce to vimtex.

Regarding your first question: Please see :h vimtex-multi-file, which explains how you can use a comment at the top of the file similar to

%! TEX root = my-main.tex

in order to set the main file. This should always work.

For your second question, the answer is currently no. The question is interesting though, as it could be a nice functionality to compile the current file outside of context of the main file. However, I don't see a simple way to do , and I am not quite sure that I want to complicate the code in order to support this. Much because there does exist a "standard" way to solve the problem through the \includes in a main file.

The same applies to your third question: vimtex works under the assumption of a single project, and does not support the idea to let a file (or set of files) be considered separate from the main file. Thus only the main file's pdf is known to vimtex.

I would be willing to discuss ideas for new features and enhancements, but I want to stress that I one of the main benefits of vimtex IMHO is that it is a clean and relatively uncomplicated code. This particular issue does seem a little bit complicated. However, if we can find small and elegant solutions that help improve support for your needs, then I will definately want to implement them.

@maxfl
Copy link
Author

maxfl commented Apr 18, 2015

I should have written that I know about '%! TEX root'. The reason I'm asking about the other way is that I have around 40 files in a project and adding this line to every file seems inelegant. Before when using LatexBox I was using autocommand to assign the necessary variable. Moreover, every file has already a '\documentclass[my-main.tex]{subfiles}' which can be reused for this purpose. Since vimtex needs a master file for the correct completions and already parses the file for the string '%!..' I think it would be quite essential to determine the main file by looking for documentclass as well.

That was the easiest part. I appreciate your desire to keep the project simple. I also currently do not see a simple way to support something like two main files. The compilation issue can be nevertheless ignored when using other tools for compilation, like 'vim-dispatcher'.

It would be pity to loose vimtex's ability for forward/backward search. The easiest way to still be able to use it is to add an optional argument for VimtexView command with the desired 'pdf' file. In this case everyone could make his own mappings.

@lervag
Copy link
Owner

lervag commented Apr 19, 2015

Could you explain in more detail how you did this with LaTeX-Box? Then I could perhaps add a similar functonality to vimtex. Are you referring to a variable such as b:tex_root or similar?

Regarding the possibility to add a custom pdf file as target for the VimtexView command, could you please open this as a separate issue with a reference to this issue and a small explanation of the feature request? I'll consider to add this functionality, as it seems slightly general and thus not breaks my philosophy to keep things simple.

However, for the compilation issue, I think I vote against it for now, since as you say this can be solved with other plugins. However, if you do have an idea for a simple implementation of this, then don't hesitate to open a feature request!

In the following I would be happy if we could keep the topic of this issue on the detection of the main file.

@maxfl
Copy link
Author

maxfl commented Apr 20, 2015

For the project I have a local .vimrc file with the following line:

au FileType tex let b:main_tex_file='main.tex'

So for each project opened in a current session the main file is set automatically.

@maxfl
Copy link
Author

maxfl commented Apr 20, 2015

Thanks for the feedback.

@lervag
Copy link
Owner

lervag commented Apr 20, 2015

No problem. I'll look into this later today or this week.

@lervag lervag closed this as completed in 3f62338 Apr 26, 2015
@lervag
Copy link
Owner

lervag commented Apr 26, 2015

This should do it, I think. I''ve named the variable b:vimtex_main. I've used your example for the explanation in the docs, see :h b:vimtex_main.

@maxfl
Copy link
Author

maxfl commented Apr 27, 2015

It works, thanks!

Sorry for bothering you with it , are you also going to add the pattern for '\documentclass[main.tex]{subfiles}' to the check of the main documents, or you consider it excessive?

@lervag
Copy link
Owner

lervag commented Apr 27, 2015

No bother!

As you already know, I've today used the assumption that there is only one \begin{document}. However, perhaps it is better to instead use a pattern against \documentclass[...]{...}. In general, there should only be one such line in a project. In your case, this would match every subfiles file. The problem then is that it would not match the correct main file, unless you use the buffer variable to set it.

So my proposal: I change the main file pattern from \begin{document} to \documentclass[...]{...}. This should (as far as I know) not break anything for anyone, but it should allow you to work with the subfiles and let every subfile be it's own main file, unless you specify the main file with a buffer variable.

One more note about the proposal: It is not as of now possible to use multiple main files, so you can not change from the subfile main to the project main interactively. However, it should be possible to create a custom function that unlet's the variables and reloads the init function...

@maxfl
Copy link
Author

maxfl commented Apr 27, 2015

It seems that there is some confusion concerning the proposals (:

My proposal was to add '\documentclass[main.tex]{subfiles}' as a pattern in the same place, where you check for '%! TeX root:main.tex'. So vimtex will determine that the current file is included in some other main file. This seems essential for me, since the main file is used to determine cite/ref completions. This of course may be done optionally, something like g:vimtex_detect_subfiles.
Since I've found subfiles on LaTeX wikibook I expect this package to be quite popular.

Concerning your proposal to switch to main file detection from \begin{document} to \documentclass[]{}. I think it is a good idea. It may be more efficient, since \documentclass is usually located earlier. There are two corner cases, when either \begin{document} or \documentclass is located in the file, included via \input, but I see no simple way to take into account all of the use cases.

@maxfl
Copy link
Author

maxfl commented Apr 27, 2015

Just in case, the subfile document has both \documentclass and \begin{document}. So it is currently is detected to be a main file, unless b:vimtex_main is set.

lervag added a commit that referenced this issue Apr 29, 2015
Added parsing of main file from `\documentclass[main.tex]{subfiles}`.
@lervag
Copy link
Owner

lervag commented Apr 29, 2015

Ah, I see. So first, based on your last comment it seems unnecessary to change the regexp as I proposed (no need to fix something that is not broken).

Now back to your proposal: I've tried to implement what you suggested. Could you test and comment? I've done some simple testing, and it looks good on my end. One thing: Do you think it is enough to parse only the first five lines (as I'm doing now), or should I increase this threshold?

Also, I chose not to add a new option. It doesn't seem necessary in my opinion.

@maxfl
Copy link
Author

maxfl commented Apr 29, 2015

It works as expected for flat projects, where included files are located in the same folder as main. For the project with tree structure, where included files are located in subfolders it fails. As far as I can understand the code it tests if file is located in the same folder as the current one, while the file is actually located in cwd. So I would also test working dir for the main file.

Concerning the number of lines. Personally I've never seen a project where \documentclass would be located not on a first line. I'm not much familiar with '%!' options though. So I guess that 5 lines should be enough.

@maxfl
Copy link
Author

maxfl commented Apr 29, 2015

Yes, it worth noting that subfiles seem not to understand '../../' main files so all the activity is done in the project root.

@lervag
Copy link
Owner

lervag commented Apr 29, 2015

That is interesting. Does subfiles internally perform a search upwards in the directory tree, then? I would think that for a project that looks like this:

* main.tex
* sub\
|-- * sub.tex

sub.tex would need \documentclass[../main.tex]{subfiles}. But this is not the case, then?

The lines that construct the main file path are:

        if candidate[0] !=# '/'
          let candidate = expand('%:h') . '/' . candidate
        endif
        let main = fnamemodify(candidate, ':p')

If candidate is not already an absolute path, we prepend the head of the current files path. Thus one use ../main.tex this should work.

@maxfl
Copy link
Author

maxfl commented Apr 29, 2015

The situation is quite primitive. For the project you describe you have \documentclass[main.tex]{subfiles}. No search is performed since you should work in the root folder and there is no way to compile sub.tex being in sub/. So you are in the root and compile with a command:

latex sub/sub.tex
or
latexmk sub/sub.tex

This actually make sense. In a projects like this there may be additional included and sty files located in the root folder. The only way latex will find them is to call it from root. I can imagine no simple way for latex to do it if called in sub.

As for me, I usually start gvim in a root folder with servername specified and noacd so whatever file I open it is compiled from within root. All the temporary files as well as output files are located in the root folder as well.

@lervag
Copy link
Owner

lervag commented Apr 30, 2015

Hmm. I've been searching for documentation that specifies things, and I found this. The example is similar to the one I've presented above, and it uses the same format as I've assumed with, that is,

\documentclass[../main.tex]{subfiles}

To me this seems the only sensible thing. When vimtex searches for the main file, it is in principle searching for the project root. Thus there is no way of knowing the project root while parsing the subfiles documentclass string.

@maxfl
Copy link
Author

maxfl commented May 1, 2015

Indeed, now it works in some cases. Nevertheless what I've written before is based on my own experience - I've failed to use relative paths when I've started using subfiles. See the following example below. You need to create sub dir and run latex once so it creates all the necessary files.

For this project you can:

  • Compile main.tex from /
  • Compile sub/abs.tex from /

And you can not:

  • Compile sub/abs.tex from /sub
  • Compile sub/rel.tex from /sub
  • Compile sub/rel.tex from /

Only if you remove \usepackage{test} you will be able to compile sub/rel.tex from /sub. So to support the both use cases you may when determining the main file one can:

  • Check the path against the current file path as it's done now.
  • Check against the vim CWD. In this case you will support projects like abs.tex from the example. As I'm trying to propose.
\begin{filecontents}{sub/rel.tex}
  \documentclass[../test.tex]{subfiles}
  \begin{document}
  relative 
  \end{document}
\end{filecontents}
\begin{filecontents}{sub/abs.tex}
  \documentclass[test.tex]{subfiles}
  \begin{document}
  absolute
  \end{document}
\end{filecontents}
\begin{filecontents}{test.sty}
\end{filecontents}

\documentclass{report}

\usepackage{subfiles}
\usepackage{test}

\begin{document}

Contents:

\subfile{sub/rel.tex}

\subfile{sub/abs.tex}
\end{document}

@lervag
Copy link
Owner

lervag commented May 1, 2015

I tested your example. And since the subfiles package itself seem to specifiy that the main file reference should be relative to the working directory, it seems you are right that I should respect the working directory.

In the latest commit, I've implemented this. It will first try relative to the current file, then it tries relative to working directory. Let me know if it works as it should.

@maxfl
Copy link
Author

maxfl commented May 2, 2015

It works as expected. Thanks!

@lervag
Copy link
Owner

lervag commented May 2, 2015

Great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants