From 662c7f54f3df0d6937751cdaaf98902a3e4f2d31 Mon Sep 17 00:00:00 2001 From: lukas Date: Thu, 26 Aug 2021 16:32:51 +0200 Subject: [PATCH] init --- Main.go | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 7 +++ go.mod | 3 + 3 files changed, 176 insertions(+) create mode 100644 Main.go create mode 100644 README.md create mode 100644 go.mod diff --git a/Main.go b/Main.go new file mode 100644 index 0000000..9513b86 --- /dev/null +++ b/Main.go @@ -0,0 +1,166 @@ +package main + +import ( + "bufio" + "fmt" + "io" + "log" + "os/exec" + "regexp" + "runtime" + "strconv" +) + +func main() { + fmt.Printf("Pdflatex command exists: %t\n", commandExists("pdflatex")) + fmt.Printf("%s/%s\n", runtime.GOOS, runtime.GOARCH) + + compileAndInstall() +} + +func compileAndInstall() { + out, err := compileLatex("main.tex") + //fmt.Println(*out) + if err != nil { + fmt.Println("An error occured while compiling the document!") + + filename := parseMissingFile(out) + if filename != "" { + fmt.Printf("We need to download: %s\n", filename) + + // now we neet to perform a root check + if rootCheck() { + log.Println("Awesome! You are now running this program with root permissions!") + + if installFile(filename) { + // if successfully installed we try to compile again + compileAndInstall() + } + } else { + log.Fatal("This program must be run as root! (sudo)") + } + } else { + fmt.Println(*out) + + fmt.Println("another build error occured!") + } + } else { + fmt.Println("document built successfully!") + } +} + +func parseMissingFile(output *string) string { + matchfile := regexp.MustCompile("! LaTeX Error: File `([^`']*)' not found|! I can't find file `([^`']*)'.") + matches := matchfile.FindStringSubmatch(*output) + fmt.Printf("%#v\n", matches) + if matches != nil { + if matches[1] != "" { + return matches[1] + } else { + return matches[2] + } + } + + // ok now we try to find a font error + fontregex := regexp.MustCompile(`! Font \\[^=]*=([^\s]*)\s`) + fontmatch := fontregex.FindStringSubmatch(*output) + fmt.Printf("%#v\n", fontmatch) + if fontmatch != nil { + if fontmatch[1] != "" { + return fontmatch[1] + } + } + + // now try babel errors + babelregex := regexp.MustCompile("Unknown option `([^`']*)'. Either you misspelled") + babelmatch := babelregex.FindStringSubmatch(*output) + if babelmatch != nil { + if babelmatch[1] != "" { + return babelmatch[1] + ".ldf" + } + } + + return "" +} + +// check if a specific system command is available +func commandExists(cmd string) bool { + _, err := exec.LookPath(cmd) + return err == nil +} + +// parse the thumbail picture from video file +func compileLatex(filename string) (*string, error) { + app := "pdflatex" + + cmd := exec.Command(app, + "-file-line-error", + "-interaction=nonstopmode", + "-synctex=1", + "-output-format=pdf", + filename) + + stdout, err := cmd.Output() + + output := string(stdout) + + return &output, err +} + +func rootCheck() bool { + cmd := exec.Command("id", "-u") + output, err := cmd.Output() + + if err != nil { + log.Fatal(err) + } + + // output has trailing \n + // need to remove the \n + // otherwise it will cause error for strconv.Atoi + // log.Println(output[:len(output)-1]) + + // 0 = root, 501 = non-root user + i, err := strconv.Atoi(string(output[:len(output)-1])) + + if err != nil { + log.Fatal(err) + } + + if i == 0 { + return true + } else { + return false + } +} + +func installFile(filename string) bool { + if !commandExists("dnf") { + fmt.Println("dnf not existing!") + return false + } + + cmd := exec.Command("dnf", "-y", "install", fmt.Sprintf("tex(%s)", filename)) + fmt.Println(cmd.String()) + + stdout, _ := cmd.StdoutPipe() + stderr, _ := cmd.StderrPipe() + + fmt.Println("running dnf install now!") + + go func() { + merged := io.MultiReader(stderr, stdout) + scanner := bufio.NewScanner(merged) + for scanner.Scan() { + m := scanner.Text() + fmt.Println(m) + } + }() + + err := cmd.Run() + if err != nil { + fmt.Println(err.Error()) + return false + } + return true +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..e58d75a --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# LatexAutoInstaller + +This application installs all neccessary latex packages to perform a successfull build. + +## Currently Supported OS + +* Fedora \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b6bc42c --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module latexautoinstaller + +go 1.16