modernc.org/knuth@v0.0.4/tex/api.go (about)

     1  // Copyright 2023 The Knuth Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:generate make generate
     6  
     7  // Package tex is the TEX program by D. E. Knuth, transpiled to Go.
     8  //
     9  //	http://mirrors.ctan.org/systems/knuth/dist/tex/tex.web
    10  package tex // modernc.org/knuth/tex
    11  
    12  import (
    13  	// Required by go:embed
    14  	_ "embed"
    15  	"fmt"
    16  	"io"
    17  	"runtime/debug"
    18  	"unsafe"
    19  
    20  	"modernc.org/knuth"
    21  )
    22  
    23  //go:embed tex.pool
    24  var pool string
    25  
    26  // program TEX; {all file names are defined dynamically}
    27  
    28  // Main executes the tex program using the supplied arguments.
    29  func Main(stdin io.Reader, stdout, stderr io.Writer) (mainErr error) {
    30  	defer func() {
    31  		switch x := recover().(type) {
    32  		case nil:
    33  			// ok
    34  		case signal:
    35  			switch {
    36  			case mainErr == nil:
    37  				mainErr = fmt.Errorf("aborted")
    38  			default:
    39  				mainErr = fmt.Errorf("aborted: %v", mainErr)
    40  			}
    41  		case knuth.Error:
    42  			mainErr = x
    43  		default:
    44  			mainErr = fmt.Errorf("PANIC %T: %[1]v, error: %v\n%s", x, mainErr, debug.Stack())
    45  		}
    46  	}()
    47  
    48  	prg := &prg{
    49  		dviFile:  knuth.NewBinaryFile(nil, nil, 1, nil),
    50  		fmtFile:  knuth.NewBinaryFile(nil, nil, int(unsafe.Sizeof(memoryWord{})), opener),
    51  		logFile:  knuth.NewTextFile(nil, nil, nil),
    52  		poolFile: knuth.NewPoolFile(pool),
    53  		stderr:   knuth.NewTextFile(nil, stderr, nil),
    54  		termIn:   knuth.NewTextFile(stdin, nil, nil),
    55  		termOut:  knuth.NewTextFile(nil, stdout, nil),
    56  		tfmFile:  knuth.NewBinaryFile(nil, nil, 1, opener),
    57  	}
    58  	for i := range prg.inputFile {
    59  		prg.inputFile[i] = knuth.NewTextFile(nil, nil, opener)
    60  	}
    61  	for i := range prg.writeFile {
    62  		prg.writeFile[i] = knuth.NewTextFile(nil, nil, nil)
    63  	}
    64  	for i := range prg.readFile {
    65  		prg.readFile[i] = knuth.NewTextFile(nil, nil, nil)
    66  	}
    67  	prg.main()
    68  	return nil
    69  }
    70  
    71  func opener(nm string) (io.Reader, error) { return knuth.Open(nm, []string{"."}) }