github.com/raphaelreyna/latte@v0.11.2-0.20220317193248-98e2fcef4eef/internal/job/compile.go (about)

     1  package job
     2  
     3  import (
     4  	"context"
     5  	"io/ioutil"
     6  	"os"
     7  	"os/exec"
     8  	"path/filepath"
     9  )
    10  
    11  // Compile creates a tex file by filling in the template with the details and then compiles
    12  // the results and returns the location of the resulting PDF.
    13  func (j *Job) Compile(ctx context.Context) (string, error) {
    14  	opts := j.Opts
    15  
    16  	// Move into the working directory
    17  	currDir, err := os.Getwd()
    18  	if err != nil {
    19  		return "", err
    20  	}
    21  	os.Chdir(j.Root)
    22  	defer os.Chdir(currDir)
    23  
    24  	// Grab a valid compiler from the options
    25  	compiler := string(CC_Default)
    26  	if cc := opts.CC; cc.IsValid() {
    27  		compiler = string(opts.CC)
    28  	}
    29  
    30  	// Create the jobname from the options
    31  	jn := filepath.Base(j.Root)
    32  	if opts.N < 1 {
    33  		opts.N = 1
    34  	}
    35  
    36  	// Create the tex file
    37  	texFile, err := ioutil.TempFile(j.Root, "*_filled-in.tex")
    38  	if err != nil {
    39  		return "", err
    40  	}
    41  	defer func() {
    42  		texFile.Close()
    43  		//os.Remove(texFile.Name())
    44  	}()
    45  
    46  	tmpl := j.Template.Option("missingkey=" + j.Opts.OnMissingKey.Val())
    47  	err = tmpl.Execute(texFile, j.Details)
    48  	if err != nil {
    49  		return "", err
    50  	}
    51  
    52  	// Compile however many times the user asked for
    53  	for count := uint(0); count < opts.N; count++ {
    54  		// Make sure the context hasn't been canceled
    55  		if err := ctx.Err(); err != nil {
    56  			return "", err
    57  		}
    58  
    59  		args := []string{"-halt-on-error", "-jobname=" + jn}
    60  		if opts.CC == CC_Latexmk {
    61  			args = append(args, "-pdf")
    62  		}
    63  		args = append(args, texFile.Name())
    64  		// Create a handle for the compiler command
    65  		cmd := exec.CommandContext(ctx, compiler, args...)
    66  
    67  		switch count {
    68  		case opts.N - 1: // capture the error on the last run
    69  			// Run command and grab its output and log it
    70  			result, err := cmd.Output()
    71  			if err != nil {
    72  				return string(result), err
    73  			}
    74  		default:
    75  			if err = cmd.Start(); err != nil {
    76  				return "", err
    77  			}
    78  			if err = cmd.Wait(); err != nil {
    79  				return "", err
    80  			}
    81  		}
    82  	}
    83  	return jn + ".pdf", nil
    84  }