Sublime Forum

How to open a file after it was build with the OS corresponding app?

#1

Today I did my first take to build a custom build logic for my markdown files:

How do I add a a cmd to open the generated output file with the program that is connected with the extension on the operating system?

I mean open .html with my default browser, open .pdf with my default pdf application and so on?

I also have a question about "working_dir" is that necessary in my scenario? And do I need to add it to each variant as well?

My build file contains the following:

{
    "selector": "text.html.markdown, text.html.markdown.gfm",
    "working_dir": "$file_path",
    "cmd": ["pandoc", "-s", "-o", "$file_base_name.html", "$file"],

    "variants": [

        { "name": "pandoc >> .docx with reference file",
          "cmd": ["pandoc", "--reference-docx=I:\\DATEN\\_Daniel\\misc\\pandoc-references\\begruendung-reference_alt.docx", "-o", "$file_base_name.docx", "$file"],
        },
        { "name": "pandoc >> .docx without reference file",
          "cmd": ["pandoc", "-o", "$file_base_name.docx", "$file"],
        },
        { "name": "pandoc >> .html",
          "cmd": ["pandoc", "-s", "-o", "$file_base_name.html", "$file"],
        },
        { "name": "pandoc >> .org",
          "cmd": ["pandoc", "-s", "-o", "$file_base_name.org", "$file"],
        },
        { "name": "pandoc >> .pdf (scrlttr2)",
          "cmd": ["pandoc",  "$file", "-o", "$file_base_name.pdf", "--template=scrlttr2dh.latex", "--smart"],
        },
        { "name": "mmd >> .html",
          "cmd": ["multimarkdown", "$file", ">", "$file_base_name.org" ],
        },
    ]
}
1 Like

#2

You have to do that within the command you execute. Typically you check that the (first) command that does the building succeeded then you issue a second command that opens the file for you. In a Unix shell you’d use something like the && operator, but since you’re using Windows you’ll have to use whatever works there. You can also put together a batch file which does all this so you don’t have to squeeze it into one command, and just call the batch file when you build.

Another alternative is to have a separate build variant that does what you want. So you manually check that it built correctly then use a second build command (usually bound to a keystroke) with that variant to view the file. This is what I do when I want to run a program that I just built.

0 Likes

#3

The && operator that @nutjob2 mentioned above works on Windows as well as Linux/MacOS, but in all three cases it requires you to use shell_cmd instead of cmd in your build file, so that the build is performed directly by the command shell instead of trying to run it as a program.

The windows start command is capable of opening a file in the associated application from the command prompt with a bit of coaxing. An example using your first variant would look like this:

{
     "name": "pandoc >> .docx with reference file",
     "shell_cmd": "pandoc --reference-docx=I:\\DATEN\\_Daniel\\misc\\pandoc-references\\begruendung-reference_alt.docx -o \"$file_base_name.docx\" \"$file\" && start \"\" \"$file_base_name.docx\"",
},

Basically shell_cmd represents what you would type directly into the command prompt to do the same thing. This means that it’s all one big string instead of an array of arguments. This also means that you need to manually wrap your file name arguments in double quotes to ensure that it will work with files that have spaces in their names.

The && tells the command prompt to only run the next command if the prior one succeeded, so as long as pandoc is well behaved, it will only try to open the result file if the conversion worked.

Here the start command takes two arguments. The first one is what the title of the window should be, which here is just an empty string because some external application is going to handle the command and it’s going to set the window title on it’s own, and the second is the file that should be opened.

If you forget to specify the window title, you end up with a command prompt whose caption is the name of the file you wanted to open, which is almost certainly not what you intended.

If there is no application set to open the kind of file that you’ve specified, you get the standard windows dialog telling you that windows doesn’t know how to open the file and asking you what to use.

From the looks of your build system which uses $file_base_name, I would say that you indeed want working_dir to be set in this case. The $file variable expands out to the full path to the file you’re editing, so your calls to pandoc will work regardless because you’re effectively saying pandoc -o C:\Users\dhbn\Documents\whatever.md (or some such).

However in this case $file_base_name would just be whatever, which means that the resulting output file will end up in some location that may or may not be in line with where the source file is, which is probably not what you want.

Top level sublime-build options are inherited by the variants, so the only thing that any particular variant needs is to be told what’s different for that particular variant (and a name).

2 Likes

#4

Thanks @OdatNurd, what a detailed explanation. Wow! I will try it tomorrow.

0 Likes