Sublime Forum

How to specify which file/document to build regardless of current open file? (Solved for a LaTeXTools specific project)

#1

Hello!

I would like to specify a “master” document in my workspace/project, such that nomatter which other document I’m currently editing, if I choose to build, it will always be the master document.

Practical example:
LaTeX project with a main.tex document (this should always be built), and several files that a included in the project (a.tex, b.tex, c.tex). I have all of them open in sublime, and cycle between editing them.

I am currently editing a.tex and decide to build. Currently I have to navigate back to the main.tex file before I build, else it will not build properly. I would like to not have to.

Further, if possible, I also want it to build, even if I am editing a random file - say latex.sublime-completions document, while the project is open.

0 Likes

#2

Your project can specify a build system. See https://www.sublimetext.com/docs/3/projects.html

0 Likes

#3

Thank you for replying.

I should perhaps have mentioned that I looked at the documentation and failed to grasp it. I’m not a professional coder by any stretch, so I really need an explanation as to how it would look in practice. Perhaps I also need to supply a concrete visual example.

Folder structure: Folders are bold, files are italics

  • work/
    • work.sublime-project
    • included/
      • included1.tex (Included in main.tex)
      • included2.tex (Included in main.tex)
    • tex/
      • main.tex (I need it to build from this file, always)
      • main.cls (used in main.tex)
      • style
        • style.tex (included in main.cls)

When I’m working on the project, I am editing various files other than the main.tex file. What do I need to write in the work.sublime-project file, in order to make it always compile the main.tex file, no matter which file I am currently editing?

0 Likes

#4

In order to have the build always execute with a specific file as the one being built, the command that you specify should use the name of that file specifically in the command.

For example:

"shell_cmd": "doTheThing \"$file\""

executes doTheThing and passes it the current file. On the other hand:

"shell_cmd": "doTheThing \"$project_path/tex/main.tex\""

This specifies that doTheThing should be executed with the file specifically provided, which here is a path relative to the location that the sublime-project file is stored inside of (based on your example above).

The video below covers projects and workspaces in Sublime, and shows a visual example of what build systems inside of your project look like and how they work. The link takes you directly to that part of the video, but if you’re unfamiliar with Projects and workspaces in general, you can watch it from the beginning.

There’s also a playlist on the channel that covers build systems in general and how they work. You may also want to check out the documentation on build systems as well, which covers the variables you can use (such as $project_path).

1 Like

#5

Thank you for your reply.

I have watched the video through and through, I have ooked at docs.sublimetextdotio both the project and build system pages, as well as the official documentation on build systems and what have you, and also the pages about the specific LaTeXTools build system latextools.readthedocsdotio. I found them all to be informative, though I am still not able to solve the problem.

As per your comment and video, I have tried the following:

{
"folders":
	[
	{
	"file_include_patterns":
		[
		"*.tex",
		"*.cls",
		],
	"path": ".",
	},
	{
	"name": "Compiling LaTeX",
    	"shell_cmd":
	     	 [
	    	 "xelatex", 
	    	 "$tex/main.tex"
       	    	 ],
    	},
    	]
}

I have a nagging thought that the information I need is whatever substitutes for “doTheThing”. I have tried to provide a path for the xelatex exe file, which did not work.

0 Likes

#6

You have a few issues here:

  • Your build system is inside of folders, but it needs to be inside of build_systems (which your project doesn’t have)
  • shell_cmd needs to be a single string that represents the command that you would enter into the terminal, but here you have a list of strings; for that you would use cmd instead.
  • $tex isn’t a variable that will expand out to anything by default, so it will be replaced with the empty string and probably not do what you want.

Fixes for these things would look something like the following for the content of your project file:

{
   "folders":[
      {
         "file_include_patterns":[
            "*.tex",
            "*.cls"
         ],
         "path":"."
      },
   ],
   "build_systems": [
      {
         "name":"Compiling LaTeX",
         "cmd":[
            "xelatex",
            "$folder/tex/main.tex"
         ]
      }
   ]
}

$folder expands out to the path of the first folder that’s added to the project, which here is the location in which the sublime-project file is stored (because the path in the folder is .).

Note that is is technically possible for $tex to expand out to something, if the build system was using a custom target key to direct something other than the default build command to execute the build.

If that’s the case then this can be further refined as well by adding additional things to this build. That only matters if the $tex part was based on the contents of an existing sublime-build file though.

3 Likes

#7

Alright. I have copied the changes, but it still does not compile main.tex whenever I press ctrl+B in any open .tex document, and it does not use xelatex, unless I choose it manually with the Build With… even when I am editing the main.tex file.

I want to make sure, there is an adequate amount of scepticism regarding my own contribution, lest some stupidity on my part is overlooked due to an excess of faith in my abilities: I don’t know whether it is meaningfuld to give the command “xelatex” - that is to say, I have done nothing outside of installing the LaTeXTools package.

Also, I don’t understand how we went from $project_path to $folder between your first and second posts. As I wrote in my response, I had tried simply writing “$tex/main.tex”, because I assumed $project_path was a placeholder of some sort. As per your second post, I have tried writing “$folder/tex/main.tex”. I assume it is important, that I understand what is a placeholder and what isn’t, and I am a little slow on the uptake on that.

0 Likes

#8

Did you select the build system from the project under Tools > Build System? With that selected it should tell Sublime to use that build directly unless you tell it otherwise or the build itself has variants (which as outlined above, it does not).

That’s not something I can help with unfortunately; my knowledge of LaTeX stops at knowing that it’s a thing that exists. However if you have something that already does the build, you can look at it to see what command it’s invoking if it’s not this one.

My bad there, sorry for the confusion (not enough coffee, I suppose). The variable $folder expands out to the full absolute path to the very first folder in the project, whereas $project_path expands out to be the absolute path of the location where the sublime-project file is stored.

In the first example, I used $project_path because from your post above the sublime-project file was inside of the work folder, so $project_path/text/main.tex becomes the absolute path to the main.tex file.

In the second example I used $folder, which expands out to the first folder in the project, which is work/ and should be the same as $project_path, so it should work the same either way.

Something that’s possibly missing from your scenario is the concept of a working directory, which is the directory that’s considered to be “current” when a program is executing.

The examples thus far don’t have anything that sets that, so the working directory can be anything (and in that case, it’s almost certainly wrong if it needs to be something specific).

I took a look at the code to the LatexTools package, but it uses weird magic to construct and execute external tasks based on things I’m unclear on since I don’t know anything about LaTex. It doesn’t seem to be trying to set a working directory, but it does seem to want to potentially set up extra arguments of some sort.

Do you know how to execute an appropriate command from the Terminal manually to generate the output that you want? If so that’s easy to put into build form.

1 Like

#9

I have tried both having it on build->automatic and also build->LaTeX. Both of which work as long as I am editing the main.tex, but as soon as I try to build on any other document, I get an error - instead of it simply choosing to build on main.tex.

When I build, it says invoking latexmk, which I suppose should be the command instead of xelatex, but it does not make a differencem when I replace it.

I don’t know whether this might be a clue, but if I Save Project As and replace my work.sublime-project, sublime deletes part of the code, as if to tell me “I don’t know what this is, so I’ll just clean that up for you.” The code that is left is just:

{
"folders":
	[
	{
	"file_include_patterns":
		[
		"*.tex",
		"*.cls"
		],
		"path": "."
	}
	]
}

I don’t know that much about building from terminal, but I’ll look into it too.

0 Likes

#10

Something to note is that in the example provided above, the build system name is Compiling Latex, not Latex. Assuming that’s not a typo on your part, you may not have selected the correct build. Builds from project files end up at the top of the menu.

I don’t think I’ve ever seen that happen, and I can’t reproduce it here. Are you sure that the build information you added was to the sublime-project file that was open in the window at the time?

1 Like

#11

I would just like to say, that I am very grateful for the amount of time you have spent on this issue. Whether this leads to a resolution of the problem or not, it is much appreciated.

As to the deletion on saving the project, yes. I have done it a couple of times, just to be sure. If I simply save work.sublime-project (ctrl+s), I can close and open the project and everything remains when I choose Edit Project. But if I make the changes and save the project as, sublime removes part of the code. I have even tried saving as another name “work1.sublime-build” and the code is still changed in the new file, but remains the same in the old. Most peculiar.

It had gone over my head, that the name was not just something random. I looked at the LaTeXTools sublime-build file (R:\portable\sublimetext3\Data\Packages\LaTeXTools\LaTeX.sublime-build), and found the following information:

"target": "make_pdf",
"selector": "text.tex.latex",

And

"variants":
    [
    {
    "name": "Traditional",
    "builder": "traditional"
    },
    {
    "name": "PdfLaTeX",
    "builder": "traditional",
    "program": "pdflatex"
    },
...
    {
    "name": "XeLaTeX",
    "builder": "traditional",
    "program": "xelatex"
    },
...
    ]

I have adjusted the project thusly:

{
"name": "XeLaTeX",
"cmd":
    [
    "xelatex", "$folder/tex/main.tex"
    ],
    "selector": "text.tex.latex",
},

When I build with my main file, I get the following output:

[Compiling R:\work\tex\main.tex]

TraditionalBuilder: Engine: xelatex. Invoking latexmk... done.

No errors. Warnings:

When I press build while editing the included file, it doesn’t switch to main.tex, it just tries to build and fails on the included file:

[Compiling R:\work\tex\included\included1.tex]

TraditionalBuilder: Engine: xelatex. Invoking latexmk... done.

Errors:

Lastly, it also seems sublime ignores what is in the project about the build. It builds whatever I have chosen from the menu or the build with panel. I would expect that given the xelatex command in the project, pressing build would override whatever build system chosen in the menu, and instead building xelatex. I would also expect it to override building whatever document I was editing when pressing build, and instead building the main.tex. It behaves as I would expect, if the code it deletes when saving as was not applied or did not work.

0 Likes

#12

Hi all,

I tried to solve this in a different direction. Take a look at “Multi-file documents” in the LaTeXTools Documentation. It worked for me.

1 Like

#13

If this is the build in the project and

appears in the output, then the build that’s being used doesn’t seem like it’s the one from the project; it looks like the build in LaTeX tools (which is in no way a standard build; among other things it has a custom target).

1 Like

#14

Hi, and thank you for replying.

Before asking the question, I looked at those pages, but I also failed to grasp it in any useful way.

I realize this is a lot to ask, but would it be possible for you to elaborate and give concrete examples of your working code. The reason I ask is that I am no coder by any stretch… I am however a psychologist specializing in learning, and I know a lot about learning strategies - especially my own, which often involve finding something that works and then bending, breaking, ammending and fixing it, and in the proces both coming to an understanding the general principle of it and customizing it to my needs.

Perhaps it is my own fault, trying to use something which might require a course or two of python, but nevertheless I hope for your goodwill.

0 Likes

#15

You are saying you are “no coder by any stretch…” Just keep in mind I am not a programmer at all.

Below is a minimal working example. The documentation provides two possibilities. The first is the following:

Create a file named file_contains_preamble.tex and paste the following code:

\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}

\begin{document}

Hello, world! This is in file\_contains\_preamble.

\input{file_does_not_contain_preamble.tex}

\end{document}

Then, create a file named file_does_not_contain_preamble.tex and paste the following code:

% !TEX root = file_contains_preamble.tex

Hello, world! This is in file\_does\_not\_contain\_preamble.

Now, put the files in the same folder. You should be able to compile from either file by using ctrl+b.

The second way to do this is by creating the first file as above, and the second file as:

Hello, world! This is in file\_does\_not\_contain\_preamble.

Now, create a project and edit it. Paste the following code in the sublime-project file:

{
	"folders":[
		{
			"path": "C:\\Users\\your_user_name\\Desktop\\example\\",
			"file_include_patterns": [
				"*.tex",
			],
		}
	],
	"settings": {
		        "TEXroot": "file_contains_preamble.tex"
		    },
}

After you save the file, compiling from either file should work.

1 Like

#16

Whatever you are, you’ve managed to solve it for me. When I looked at the LaTeX documentation the first time, I misunderstood where to put the “% !TEX root = main.tex”, but your explanation made it clear. Thank you very much!

0 Likes