github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/docgen/api/render.go (about)

     1  package docgen
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	golog "log"
     8  	"os"
     9  )
    10  
    11  var (
    12  	// ReadOnly defined whether docgen should write rendered documents to disk.
    13  	// This option is useful for testing config
    14  	ReadOnly bool
    15  
    16  	// Panic defined whether errors should raise a panic. This is useful for
    17  	// debugging because a stack trace gets raised.
    18  	Panic bool
    19  )
    20  
    21  // Render runs docgen
    22  func Render() (err error) {
    23  	defer func() {
    24  		// Write a stack trace on error
    25  		if !Panic {
    26  			if r := recover(); r != nil {
    27  				err = fmt.Errorf("%s", r)
    28  			}
    29  		}
    30  	}()
    31  
    32  	walkSourcePath(Config.SourcePath)
    33  
    34  	if !unique() {
    35  		golog.Print("[ERROR] duplicate DocumentID found")
    36  	}
    37  
    38  	renderAll(Documents)
    39  
    40  	return
    41  }
    42  
    43  func fileWriter(path string) *os.File {
    44  	if ReadOnly {
    45  		return nil
    46  	}
    47  
    48  	f, err := os.OpenFile(path, os.O_TRUNC|os.O_WRONLY|os.O_CREATE, 0644)
    49  	if err != nil {
    50  		panic(err.Error())
    51  	}
    52  	return f
    53  }
    54  
    55  func renderAll(docs documents) {
    56  	for cat := range Config.Categories {
    57  		for i := range Config.Categories[cat].Templates {
    58  			renderInnerLoop(&Config.Categories[cat].Templates[i], docs)
    59  		}
    60  	}
    61  }
    62  
    63  func renderInnerLoop(t *templates, docs documents) {
    64  	makePath(t.OutputPath)
    65  
    66  	for d := range docs {
    67  		if docs[d].CategoryID == t.ref.ID {
    68  			renderDocument(t, &docs[d], docs)
    69  		}
    70  	}
    71  	renderCategory(t, docs)
    72  }
    73  
    74  func renderDocument(t *templates, d *document, docs documents) {
    75  	if t.docTemplate == nil {
    76  		return
    77  	}
    78  
    79  	f := fileWriter(t.DocumentFilePath(d))
    80  	b := new(bytes.Buffer)
    81  
    82  	log("Rendering document", d.DocumentID)
    83  
    84  	err := t.docTemplate.Execute(b, t.DocumentValues(d, docs, true))
    85  	if err != nil {
    86  		panic(err.Error())
    87  	}
    88  
    89  	if len(Config.renderedDocuments[t.ref.ID]) == 0 {
    90  		Config.renderedDocuments[t.ref.ID] = make(map[string][]string)
    91  	}
    92  	Config.renderedDocuments[t.ref.ID][d.DocumentID] = append(
    93  		Config.renderedDocuments[t.ref.ID][d.DocumentID],
    94  		b.String(),
    95  	)
    96  
    97  	write(f, b)
    98  }
    99  
   100  func renderCategory(t *templates, docs documents) {
   101  	if t.catTemplate == nil {
   102  		return
   103  	}
   104  
   105  	f := fileWriter(t.CategoryFilePath())
   106  	b := new(bytes.Buffer)
   107  
   108  	log("Rendering category", t.ref.ID)
   109  
   110  	err := t.catTemplate.Execute(b, t.CategoryValues(docs))
   111  	if err != nil {
   112  		panic(err.Error())
   113  	}
   114  
   115  	Config.renderedCategories[t.ref.ID] = append(
   116  		Config.renderedCategories[t.ref.ID],
   117  		b.String(),
   118  	)
   119  
   120  	write(f, b)
   121  }
   122  
   123  func write(f *os.File, b io.Reader) {
   124  	if ReadOnly {
   125  		return
   126  	}
   127  
   128  	_, err := io.Copy(f, b)
   129  	if err != nil {
   130  		panic(err.Error())
   131  	}
   132  
   133  	err = f.Close()
   134  	if err != nil {
   135  		panic(err.Error())
   136  	}
   137  }